有了回测的结果,需要可视化呈现,便于查看。
结果包含两大部分,一部分是dataframe保存的时间序列,需要呈现的是权益曲线,另一部分是重要的收益、风险相关的值,比如收益率,年化收益率,夏普比等。
时间序列相关,选择用plotly绘制,一是图表美观,二是使用简单,直接兼容dataframe。(pyecharts不太好看,且不直接支持dataframe,毕竟是个人小团队在维护)
写一个较为通用的模块:
import plotly.plotly as py
import plotly.tools as tls
import plotly.graph_objs as go
import plotly
from plotly.graph_objs import *
import plotly.graph_objs as go # 必须有个
import pandas as pd
from datetime import datetime
def plot_df2html(df,cols,title,x_title='日期',y_title=''):
datas = []
for col in cols:
item = go.Scatter(x=df.index, y=df[col], name=col)
datas.append(item)
layout = dict(title=title,xaxis=dict(title=x_title,rangeslider=dict()),yaxis=dict(title=y_title))
fig = go.Figure(data =datas,layout=layout)
plotly.offline.plot(fig, filename='output.html',auto_open=True)
另外一部分是回测结果呈现,这里选择参数表:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets,QtCore
from pyqtgraph.parametertree import ParameterTree
from pyqtgraph.parametertree import Parameter
from qtpy import QtCore
from qtpy.QtWebEngineWidgets import QWebEngineView
class WidgetParams(ParameterTree):
def __init__(self):
super(WidgetParams, self).__init__()
def show_datas(self,datas):
#datas = [{'name':xxx,children:},{}]
params = []
for data in datas: #data是一个个dict
param_children = []
for data_child in data['children']:
data_child_name = data_child['name']
data_child_value = data_child['value']
param_children.append({'name': data_child_name, 'type': 'float', 'value': data_child_value})
param = {'name': data['name'], 'type': 'group', 'children': param_children}
params.append(param)
## 创建参数对象树
p = Parameter.create(name='params', type='group', children=params)
self.setParameters(p, showTop=False)
self.setHeaderLabels(["参数", "数值"])
if __name__ == '__main__':
# 创建参数树的数据
params = [
{'name': '基本收益信息', 'type': 'group', 'children': [
{'name': '回测收益', 'type': 'float', 'value': 132.836, 'siPrefix': True, 'suffix': '%'},
{'name': '回测年化收益', 'type': 'float', 'value': 32.712, 'step': 0.1, 'siPrefix': True, 'suffix': '%'},
{'name': '基准收益', 'type': 'float', 'value': 48.261},
{'name': '基准年化收益', 'type': 'float', 'value': 14.096, 'step': 0.01},
]},
{'name': '风险指标', 'type': 'group', 'children': [
{'name': 'Beta', 'type': 'float', 'value': 0.4580},
{'name': '夏普比', 'type': 'float', 'value': 1.2993},
{'name': '最大回撤', 'type': 'float', 'value': 16.295, 'step': 10, 'siPrefix': True, 'suffix': '%'},
]},
]
datas = [
{
'name':'收益信息',
'children':[
{'name': '回测收益','value': 132.836},
{'name': '回测年化收益', 'value': 32.712},
{'name': '基准收益', 'value': 48.261},
{'name': '基准年化收益', 'value': 14.096},
]
},
{
'name': '风险指标',
'children': [
{'name': 'Beta', 'value': 0.4580},
{'name': '夏普比','value': 1.2993},
{'name': '最大回撤','value': 16.295},
]
}
]
app = QApplication(sys.argv)
demo = WidgetParams()
demo.show_data(datas)
demo.show()
sys.exit(app.exec_())
最终呈现的界面长这样:
联系客服