有了回测的结果,需要可视化呈现,便于查看。 结果包含两大部分,一部分是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_())
最终呈现的界面长这样:
|