[update] bugfix;股票实盘多K线时提供选择框
This commit is contained in:
parent
db50cc11e4
commit
23acc8ff8f
@ -482,7 +482,7 @@ class CtaEngine(BaseEngine):
|
||||
|
||||
# Check if sending order successful
|
||||
if not vt_orderid:
|
||||
vt_orderids
|
||||
return vt_orderids
|
||||
|
||||
vt_orderids.append(vt_orderid)
|
||||
|
||||
|
@ -1570,15 +1570,34 @@ class CtaEngine(BaseEngine):
|
||||
else:
|
||||
self.write_log(f'策略缓存文件不存在:{cache_file}')
|
||||
|
||||
def get_strategy_snapshot(self, strategy_name):
|
||||
"""实时获取策略的K线切片(比较耗性能)"""
|
||||
def get_strategy_kline_names(self, strategy_name):
|
||||
"""
|
||||
获取策略实例内的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)
|
||||
if strategy is None:
|
||||
return None
|
||||
|
||||
try:
|
||||
# 5.保存策略切片
|
||||
snapshot = strategy.get_klines_snapshot()
|
||||
# 5.获取策略切片
|
||||
snapshot = strategy.get_klines_snapshot(include_kline_names)
|
||||
if not snapshot:
|
||||
self.write_log(f'{strategy_name}返回得K线切片数据为空')
|
||||
return None
|
||||
|
@ -575,6 +575,28 @@ class CtaStockTemplate(CtaTemplate):
|
||||
self.write_error(f'加载缓存K线数据失败:{str(ex)}')
|
||||
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=[]):
|
||||
"""
|
||||
返回当前klines的切片数据
|
||||
@ -747,6 +769,8 @@ class CtaStockTemplate(CtaTemplate):
|
||||
dist_record['operation'] = 'sell'
|
||||
pos.volume -= trade.volume
|
||||
|
||||
self.positions[trade.vt_symbol] = pos
|
||||
|
||||
self.save_dist(dist_record)
|
||||
|
||||
def on_order(self, order: OrderData):
|
||||
@ -1122,7 +1146,6 @@ class CtaStockTemplate(CtaTemplate):
|
||||
else:
|
||||
self.write_log(f'{vt_symbol} 已委托卖出,{sell_volume},委托价:{sell_price}, 数量:{sell_volume}')
|
||||
|
||||
|
||||
def tns_finish_sell_grid(self, grid:CtaGrid):
|
||||
"""
|
||||
事务完成卖出网格
|
||||
|
@ -290,11 +290,19 @@ class StrategyManager(QtWidgets.QFrame):
|
||||
|
||||
def view_strategy_snapshot(self):
|
||||
"""实时查看策略切片"""
|
||||
snapshot = self.cta_engine.get_strategy_snapshot(self.strategy_name)
|
||||
if snapshot is None:
|
||||
return
|
||||
ui_snapshot = UiSnapshot()
|
||||
ui_snapshot.show(snapshot_file="", d=snapshot)
|
||||
kline_info = self.cta_engine.get_strategy_kline_names(self.strategy_name)
|
||||
|
||||
selector = KlineSelectDialog(kline_info,self.strategy_name)
|
||||
n = selector.exec_()
|
||||
|
||||
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):
|
||||
"""
|
||||
@ -397,6 +405,72 @@ class LogMonitor(BaseMonitor):
|
||||
super(LogMonitor, self).insert_new_row(data)
|
||||
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):
|
||||
"""
|
||||
|
@ -7,7 +7,7 @@ from enum import Enum
|
||||
from logging import INFO, ERROR
|
||||
import json
|
||||
import numpy as np
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
from vnpy.trader.constant import Direction # noqa
|
||||
|
||||
|
||||
|
@ -201,7 +201,13 @@ class TdxStockData(object):
|
||||
self.connection_status = True
|
||||
|
||||
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
|
||||
|
||||
def disconnect(self):
|
||||
|
@ -163,6 +163,7 @@ class Interval(Enum):
|
||||
HOUR = "1h"
|
||||
DAILY = "d"
|
||||
WEEKLY = "w"
|
||||
MONTHLY = 'M'
|
||||
RENKO = 'renko'
|
||||
|
||||
|
||||
|
@ -397,6 +397,7 @@ class TradeMonitor(BaseMonitor):
|
||||
"tradeid": {"display": "成交号 ", "cell": BaseCell, "update": False},
|
||||
"orderid": {"display": "委托号", "cell": BaseCell, "update": False},
|
||||
"symbol": {"display": "代码", "cell": BaseCell, "update": False},
|
||||
"name": {"display": "名称", "cell": BaseCell, "update": False},
|
||||
"exchange": {"display": "交易所", "cell": EnumCell, "update": False},
|
||||
"direction": {"display": "方向", "cell": DirectionCell, "update": False},
|
||||
"offset": {"display": "开平", "cell": EnumCell, "update": False},
|
||||
@ -419,6 +420,7 @@ class OrderMonitor(BaseMonitor):
|
||||
headers: Dict[str, dict] = {
|
||||
"orderid": {"display": "委托号", "cell": BaseCell, "update": False},
|
||||
"symbol": {"display": "代码", "cell": BaseCell, "update": False},
|
||||
"name": {"display": "名称", "cell": BaseCell, "update": False},
|
||||
"exchange": {"display": "交易所", "cell": EnumCell, "update": False},
|
||||
"type": {"display": "类型", "cell": EnumCell, "update": False},
|
||||
"direction": {"display": "方向", "cell": DirectionCell, "update": False},
|
||||
|
Loading…
Reference in New Issue
Block a user