可视化页面搭建
1、基础页
在基础页面主要涉及以下功能:
- 1、展示初始投资资金
- 2、设置时间模式
- 2.1使用回测年数
- 2.2使用回测开始结束时间
- 3、回测结果设置
1、展示初始投资资金
在这个方法中可以让用户自定义设置初始投资资金,以及搭建一个基础页面的基础类
# 继承两个类,一个处理时间模式设置,一个处理回测结果设置
class WidgetRunTT(WidgetTrad, WidgetTime):
"""基础设置界面:初始资金,回测开始,结束周期等"""
def __init__(self):
"""初始化基础回测设置界面"""
# 初始资金
self.cash = widgets.BoundedIntText(
value=1000000,
min=10000,
max=999999999,
step=1,
description='初始资金:',
disabled=False
)
# 时间模式设置
tm_box = self.init_time_mode_ui()
# 回测结果设置
metrics_box = self.init_metrics_ui()
# 通过VBox功能将其展示到页面上
self.widget = widgets.VBox([self.cash, tm_box, metrics_box])
基础类已经完成,但是其中的时间模式设置以及回测结果设置还没有。
2、时间模式设置(init_time_mode_ui)
class WidgetTime(object):
"""
便于上层widgte使用self去获取设置,统一上层使用
混入类:基础时间模式设置:
1. 年数模式
2. 开始结束模式
"""
# noinspection PyProtectedMember
def init_time_mode_ui(self):
"""构建基础 return widgets.VBox"""
# 回测时间模式
self.time_mode = widgets.RadioButtons(
options={'使用回测年数': 0,
'使用回测开始结束日期': 1},
value=0,
description='时间模式:',
disabled=False
)
self.time_mode.observe(self.on_time_mode_change, names='value')
# 年数模式
self.run_years = widgets.BoundedIntText(
value=2,
min=1,
max=6,
step=1,
description='回测年数:',
disabled=False
)
# 开始结束模式
self.start = widgets.Text(
value='2015-01-01',
placeholder='年-月-日',
description='开始日期:',
disabled=False
)
self.end = widgets.Text(
value='2019-04-26',
placeholder='年-月-日',
description='结束日期:',
disabled=False
)
self.run_years.disabled = False
self.start.disabled = True
self.end.disabled = True
return widgets.VBox([self.time_mode, self.run_years, self.start, self.end])
def on_time_mode_change(self, change):
"""切换使用年数还是起始,结束时间做为回测参数"""
if change['new'] == 0:
self.run_years.disabled = False
self.start.disabled = True
self.end.disabled = True
else:
self.run_years.disabled = True
self.start.disabled = False
self.end.disabled = False
3、回测输出设置(init_metrics_ui)
class WidgetTrad(object):
"""
回测输出设置:
1. 输出度量对象:
1. 只输出交易单:orders_pd
2. 只输出行为单:action_pd
3. 只输出资金单:capital_pd
4. 同时输出交易单,行为单,资金单(orders_pd, action_pd, capital_pd)
2. 输出交易单最大行列显示设置:
1. 默认最大行显示50
2. 默认最大列显示50
3. 是否将交易单,行为单,资金单保存在本地output文件中
"""
def init_metrics_ui(self):
"""构建基础 return widgets.VBox"""
self.metrics_out_put = widgets.RadioButtons(
options={'只输出交易单:orders_pd': 0,
'只输出行为单:action_pd': 1,
'只输出资金单:capital_pd': 2,
'输出交易单,行为单,资金单': 3},
value=0,
description='输出对象:',
disabled=False
)
out_put_display_max_label1 = widgets.Label('输出显示最大行列数,最大100行,100列',
layout=widgets.Layout(width='300px', align_items='stretch'))
out_put_display_max_label2 = widgets.Label('如需查看更多输出表单,请选择保存输出至文件',
layout=widgets.Layout(width='300px', align_items='stretch'))
self.out_put_display_max_rows = widgets.IntSlider(
value=50,
min=1,
max=100,
step=1,
description='行数',
disabled=False,
orientation='horizontal',
readout=True,
readout_format='d'
)
self.out_put_display_max_columns = widgets.IntSlider(
value=50,
min=1,
max=100,
step=1,
description='列数',
disabled=False,
orientation='horizontal',
readout=True,
readout_format='d'
)
out_put_display = widgets.VBox([out_put_display_max_label1,
out_put_display_max_label2,
self.out_put_display_max_rows,
self.out_put_display_max_columns])
save_out_put_lable = widgets.Label('是否保存交易单,行为单,资金单到文件',
layout=widgets.Layout(width='300px', align_items='stretch'))
save_out_put_lable2 = widgets.Label('路径:{}'.format(os.path.join(settings.BASE_DIR, 'out_put')),
layout=widgets.Layout(width='300px', align_items='stretch'))
self.save_out_put = widgets.Checkbox(
value=False,
description='保存输出',
disabled=False,
)
save_out_put = widgets.VBox([save_out_put_lable,
save_out_put_lable2,
self.save_out_put])
accordion = widgets.Accordion()
accordion.children = [widgets.VBox([self.metrics_out_put, out_put_display, save_out_put])]
accordion.set_title(0, '回测度量结果设置')
return accordion
2、股池页
涉及功能:
- 1、股池区,用于存放选择的股票
- 点击选中的股票可以将其删除
- 2、选股区,选择需要回测股票
- 点击选择的股票可以将其添加到股池区
- 3、搜索区
- 输入股票代码返回对应股票信息,可以选择添加进入股票池
1、股池区
class StockPool(WidgetBase):
"""股票池选股ui界面"""
# noinspection PyProtectedMember
def __init__(self):
"""构建股票池选股ui界面"""
label_layout = widgets.Layout(width='300px', align_items='stretch', justify_content='space-between')
# 股票池多选框
self.choice_symbols = widgets.SelectMultiple(
description='股池:',
disabled=False,
layout=widgets.Layout(width='300px', align_items='stretch', justify_content='space-between')
)
self.choice_symbols.observe(self.choice_symbols_select, names='value')
# 构建所有沙盒中的数据序列
market_title = ['A股'] # 因为目前国内股票历史数据只有A股是免费获取,其他例如美股、港股需要花钱获取,所以先以A股进行测试
cn_seed_symbol = [('{}:{}'.format(name[0], symbol))
for symbol, name in stock_list.get_stock_list(stock_list.K_SAND_BOX_CN).items()]
self.market_dict = {'A股': cn_seed_symbol,}
# 一个市场一个tab,tab中的symbol为沙盒中的symbol
self.market_widget_tab = widgets.Tab()
self.market_symbol_widget = []
for title in market_title:
market_symbol = widgets.SelectMultiple(
options=self.market_dict[title],
description=title,
disabled=False
)
market_symbol.observe(self.on_already_select, names='value')
self.market_symbol_widget.append(market_symbol)
self.market_widget_tab.children = self.market_symbol_widget
for ind, name in enumerate(market_title):
self.market_widget_tab.set_title(ind, name)
self.sc_box = WidgetSearchBox(self.on_already_select)()
self.widget = widgets.VBox([self.choice_symbols, self.market_widget_tab,self.sc_box])
2、选股区
def on_already_select(self, select):
"""搜索框或者内置沙盒symbol中点击放入股票池"""
st_symbol = [symbol.split(':')[1] if symbol.find(':') > 0
else symbol for symbol in list(select['new'])]
# 更新股票池中原有的symbol序列
self.choice_symbols.options = list(set(st_symbol + list(self.choice_symbols.options)))
def choice_symbols_select(self, select):
"""股票池中点击删除股票池中对应的symbol"""
self.choice_symbols.options = list(set(self.choice_symbols.options) - set(select['new']))