[update] bugfix;股票实盘多K线时提供选择框

This commit is contained in:
msincenselee 2021-09-20 07:25:45 +08:00
parent db50cc11e4
commit 23acc8ff8f
8 changed files with 138 additions and 13 deletions

View File

@ -482,7 +482,7 @@ class CtaEngine(BaseEngine):
# Check if sending order successful # Check if sending order successful
if not vt_orderid: if not vt_orderid:
vt_orderids return vt_orderids
vt_orderids.append(vt_orderid) vt_orderids.append(vt_orderid)

View File

@ -1570,15 +1570,34 @@ class CtaEngine(BaseEngine):
else: else:
self.write_log(f'策略缓存文件不存在:{cache_file}') self.write_log(f'策略缓存文件不存在:{cache_file}')
def get_strategy_snapshot(self, strategy_name): def get_strategy_kline_names(self, strategy_name):
"""实时获取策略的K线切片比较耗性能""" """
获取策略实例内的K线名称
:param strategy_name:策略实例名称
:return:
"""
info = {}
strategy = self.strategies.get(strategy_name, None)
if strategy is None:
return info
if hasattr(strategy, 'get_klines_info'):
info = strategy.get_klines_info()
return info
def get_strategy_snapshot(self, strategy_name, include_kline_names=[]):
"""
实时获取策略的K线切片比较耗性能
:param strategy_name: 策略实例
:param include_kline_names: 指定若干kline名称
:return:
"""
strategy = self.strategies.get(strategy_name, None) strategy = self.strategies.get(strategy_name, None)
if strategy is None: if strategy is None:
return None return None
try: try:
# 5.保存策略切片 # 5.获取策略切片
snapshot = strategy.get_klines_snapshot() snapshot = strategy.get_klines_snapshot(include_kline_names)
if not snapshot: if not snapshot:
self.write_log(f'{strategy_name}返回得K线切片数据为空') self.write_log(f'{strategy_name}返回得K线切片数据为空')
return None return None

View File

@ -575,6 +575,28 @@ class CtaStockTemplate(CtaTemplate):
self.write_error(f'加载缓存K线数据失败:{str(ex)}') self.write_error(f'加载缓存K线数据失败:{str(ex)}')
return None return None
def get_klines_info(self):
"""
返回当前所有kline的信息
:return: {"股票中文":[kline_name1, kline_name2]}
"""
info = {}
for kline_name in list(self.klines.keys()):
# 策略中如果kline不是按照 vtsymbol_xxxx 的命名方式,需要策略内部自行实现方法
vt_symbol = kline_name.split('_')[0]
# vt_symbol => 中文名
cn_name = self.cta_engine.get_name(vt_symbol)
# 添加到列表 => 排序
kline_names = info.get(cn_name, [])
kline_names.append(kline_name)
kline_names = sorted(kline_names)
# 更新
info[cn_name] = kline_names
return info
def get_klines_snapshot(self, include_kline_names=[]): def get_klines_snapshot(self, include_kline_names=[]):
""" """
返回当前klines的切片数据 返回当前klines的切片数据
@ -747,6 +769,8 @@ class CtaStockTemplate(CtaTemplate):
dist_record['operation'] = 'sell' dist_record['operation'] = 'sell'
pos.volume -= trade.volume pos.volume -= trade.volume
self.positions[trade.vt_symbol] = pos
self.save_dist(dist_record) self.save_dist(dist_record)
def on_order(self, order: OrderData): def on_order(self, order: OrderData):
@ -1122,7 +1146,6 @@ class CtaStockTemplate(CtaTemplate):
else: else:
self.write_log(f'{vt_symbol} 已委托卖出,{sell_volume},委托价:{sell_price}, 数量:{sell_volume}') self.write_log(f'{vt_symbol} 已委托卖出,{sell_volume},委托价:{sell_price}, 数量:{sell_volume}')
def tns_finish_sell_grid(self, grid:CtaGrid): def tns_finish_sell_grid(self, grid:CtaGrid):
""" """
事务完成卖出网格 事务完成卖出网格

View File

@ -290,11 +290,19 @@ class StrategyManager(QtWidgets.QFrame):
def view_strategy_snapshot(self): def view_strategy_snapshot(self):
"""实时查看策略切片""" """实时查看策略切片"""
snapshot = self.cta_engine.get_strategy_snapshot(self.strategy_name) kline_info = self.cta_engine.get_strategy_kline_names(self.strategy_name)
if snapshot is None:
return selector = KlineSelectDialog(kline_info,self.strategy_name)
ui_snapshot = UiSnapshot() n = selector.exec_()
ui_snapshot.show(snapshot_file="", d=snapshot)
if n == selector.Accepted:
klines = selector.get_klines()
if len(klines) > 0:
snapshot = self.cta_engine.get_strategy_snapshot(self.strategy_name,klines)
if snapshot is None:
return
ui_snapshot = UiSnapshot()
ui_snapshot.show(snapshot_file="", d=snapshot)
class DataMonitor(QtWidgets.QTableWidget): class DataMonitor(QtWidgets.QTableWidget):
""" """
@ -397,6 +405,72 @@ class LogMonitor(BaseMonitor):
super(LogMonitor, self).insert_new_row(data) super(LogMonitor, self).insert_new_row(data)
self.resizeRowToContents(0) self.resizeRowToContents(0)
class KlineSelectDialog(QtWidgets.QDialog):
"""
多K线选择窗口
"""
def __init__(
self, info: dict, strategy_name:str
):
"""
构造函数
:param info: 所有k线的配置
:param strategy_name:
"""
super(KlineSelectDialog, self).__init__()
self.info = info
self.strategy_name = strategy_name
self.t = None
self.select_names = []
self.init_ui()
def init_ui(self):
""""""
form = QtWidgets.QFormLayout()
self.t = QtWidgets.QTableWidget(len(self.info), 2)
self.t.setHorizontalHeaderLabels(['股票', 'K线'])
row = 0
for k, v in self.info.items():
item = QtWidgets.QTableWidgetItem()
item.setText(k)
self.t.setItem(row, 0, item)
klines = QtWidgets.QTableWidgetItem()
klines.setText(','.join(v))
self.t.setItem(row,1, klines)
row +=1
# 单选
self.t.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
# self.t.cellPressed.conect(self.cell_select)
form.addWidget(self.t)
button = QtWidgets.QPushButton('确定')
button.clicked.connect(self.accept)
form.addRow(button)
self.setLayout(form)
def cell_select(self,row,col):
try:
content = self.t.item(row,0).text()
self.select_names = self.info.get(content,[])
except Exception as ex:
pass
def get_klines(self):
""""""
selectedItems = self.t.selectedItems()
for item in selectedItems:
cur_row = item.row()
content = item.text()
self.select_names = self.info.get(content, [])
if len(self.select_names) > 0:
return self.select_names
return self.select_names
class SettingEditor(QtWidgets.QDialog): class SettingEditor(QtWidgets.QDialog):
""" """

View File

@ -7,7 +7,7 @@ from enum import Enum
from logging import INFO, ERROR from logging import INFO, ERROR
import json import json
import numpy as np import numpy as np
import datetime from datetime import datetime
from vnpy.trader.constant import Direction # noqa from vnpy.trader.constant import Direction # noqa

View File

@ -201,7 +201,13 @@ class TdxStockData(object):
self.connection_status = True self.connection_status = True
except Exception as ex: except Exception as ex:
self.write_log(u'连接服务器tdx异常:{},{}'.format(str(ex), traceback.format_exc())) self.write_log(u'连接服务器{}tdx异常:{},{}'.format(self.best_ip,str(ex), traceback.format_exc()))
cur_ip = self.best_ip.get('ip',None)
if cur_ip is not None and cur_ip not in self.exclude_ips:
self.write_log(f'排除{cur_ip}')
self.exclude_ips.append(cur_ip)
self.best_ip = {}
return return
def disconnect(self): def disconnect(self):

View File

@ -163,6 +163,7 @@ class Interval(Enum):
HOUR = "1h" HOUR = "1h"
DAILY = "d" DAILY = "d"
WEEKLY = "w" WEEKLY = "w"
MONTHLY = 'M'
RENKO = 'renko' RENKO = 'renko'

View File

@ -397,6 +397,7 @@ class TradeMonitor(BaseMonitor):
"tradeid": {"display": "成交号 ", "cell": BaseCell, "update": False}, "tradeid": {"display": "成交号 ", "cell": BaseCell, "update": False},
"orderid": {"display": "委托号", "cell": BaseCell, "update": False}, "orderid": {"display": "委托号", "cell": BaseCell, "update": False},
"symbol": {"display": "代码", "cell": BaseCell, "update": False}, "symbol": {"display": "代码", "cell": BaseCell, "update": False},
"name": {"display": "名称", "cell": BaseCell, "update": False},
"exchange": {"display": "交易所", "cell": EnumCell, "update": False}, "exchange": {"display": "交易所", "cell": EnumCell, "update": False},
"direction": {"display": "方向", "cell": DirectionCell, "update": False}, "direction": {"display": "方向", "cell": DirectionCell, "update": False},
"offset": {"display": "开平", "cell": EnumCell, "update": False}, "offset": {"display": "开平", "cell": EnumCell, "update": False},
@ -419,6 +420,7 @@ class OrderMonitor(BaseMonitor):
headers: Dict[str, dict] = { headers: Dict[str, dict] = {
"orderid": {"display": "委托号", "cell": BaseCell, "update": False}, "orderid": {"display": "委托号", "cell": BaseCell, "update": False},
"symbol": {"display": "代码", "cell": BaseCell, "update": False}, "symbol": {"display": "代码", "cell": BaseCell, "update": False},
"name": {"display": "名称", "cell": BaseCell, "update": False},
"exchange": {"display": "交易所", "cell": EnumCell, "update": False}, "exchange": {"display": "交易所", "cell": EnumCell, "update": False},
"type": {"display": "类型", "cell": EnumCell, "update": False}, "type": {"display": "类型", "cell": EnumCell, "update": False},
"direction": {"display": "方向", "cell": DirectionCell, "update": False}, "direction": {"display": "方向", "cell": DirectionCell, "update": False},