From 14eb6ff626b07230830248ee6aea8923a5a887f4 Mon Sep 17 00:00:00 2001 From: msincenselee Date: Wed, 9 Jun 2021 21:25:18 +0800 Subject: [PATCH] [bug fix] --- vnpy/app/cta_strategy_pro/back_testing.py | 27 +++- vnpy/app/cta_strategy_pro/template.py | 17 ++- vnpy/component/cta_grid_trade.py | 22 ++-- vnpy/data/tdx/tdx_common.py | 22 ++-- vnpy/gateway/ctp/ctp_gateway.py | 5 +- vnpy/task/celery_app.py | 14 ++- vnpy/trader/constant.py | 142 ++++++++++++++++++++++ vnpy/trader/utility.py | 7 +- 8 files changed, 229 insertions(+), 27 deletions(-) diff --git a/vnpy/app/cta_strategy_pro/back_testing.py b/vnpy/app/cta_strategy_pro/back_testing.py index ec989edd..eb2fd2ae 100644 --- a/vnpy/app/cta_strategy_pro/back_testing.py +++ b/vnpy/app/cta_strategy_pro/back_testing.py @@ -2343,7 +2343,7 @@ class BackTestingEngine(object): 'task_start_time': datetime.now(), # 任务开始执行时间 'run_host': socket.gethostname(), # 任务运行得host主机 'test_setting': self.test_setting, # 回测参数 - 'strategy_setting': self.strategy_setting, # 策略参数 + 'strategy_setting': binary.Binary(zlib.compress(pickle.dumps(self.strategy_setting))) # 策略参数(二进制保存) } # 去除包含"."的域 if 'symbol_datas' in d['test_setting'].keys(): @@ -2409,7 +2409,8 @@ class BackTestingEngine(object): d.update({'task_finish_time': datetime.now()}) # 更新回测完成时间 d.update({'trade_list': binary.Binary(zlib.compress(pickle.dumps(self.trade_pnl_list)))}) # 更新交易记录 d.update({'daily_list': binary.Binary(zlib.compress(pickle.dumps(self.daily_list)))}) # 更新每日净值记录 - + strategy_json_datas = self.get_all_strategy_json_data() + d.update({'strategy_json_datas': binary.Binary(zlib.compress(pickle.dumps(strategy_json_datas)))}) self.write_log(u'更新回测结果至数据库') self.mongo_api.db_update( @@ -2419,6 +2420,28 @@ class BackTestingEngine(object): data_dict=d, replace=False) + def get_all_strategy_json_data(self): + """获取所有策略得json数据""" + data = {} + + for strategy_name, strategy in self.strategies.items(): + try: + strategy_data = {} + if hasattr(strategy, 'get_policy_json'): + policy_json = strategy.get_policy_json() + if policy_json: + strategy_data['Policy'] = policy_json + if hasattr(strategy, 'get_grid_trade_json'): + grid_trade_json = strategy.get_grid_trade_json() + if grid_trade_json: + strategy_data['Grids'] = grid_trade_json + if strategy_data: + data[strategy_name] = strategy_data + except Exception as ex: + self.write_error(msg=f'获取策略{strategy_name}得json数据异常.{str(ex)}') + + return data + def put_strategy_event(self, strategy: CtaTemplate): """发送策略更新事件,回测中忽略""" pass diff --git a/vnpy/app/cta_strategy_pro/template.py b/vnpy/app/cta_strategy_pro/template.py index e736bb0c..86f7e8aa 100644 --- a/vnpy/app/cta_strategy_pro/template.py +++ b/vnpy/app/cta_strategy_pro/template.py @@ -851,7 +851,7 @@ class CtaProTemplate(CtaTemplate): #if not self.backtesting: if len(self.vt_symbol) > 0 and self.vt_symbol not in pos_symbols: pos_symbols.add(self.vt_symbol) - if len(self.idx_symbol) > 0 and self.idx_symbol not in pos_symbols: + if self.idx_symbol and self.idx_symbol not in pos_symbols: pos_symbols.add(self.idx_symbol) # 如果持仓的合约,不在self.vt_symbol中,需要订阅 for symbol in list(pos_symbols): @@ -889,6 +889,21 @@ class CtaProTemplate(CtaTemplate): self.write_log(u'当前持仓:{}'.format(pos_list)) return pos_list + def get_policy_json(self): + """获取policy的json格式数据""" + if not self.policy: + return None + + data = self.policy.to_json() + return data + + def get_grid_trade_json(self): + """获取gt组件的json格式数据""" + if not self.gt: + return None + data = self.gt.to_json() + return data + def tns_cancel_logic(self, dt, force=False): "撤单逻辑""" if len(self.active_orders) < 1: diff --git a/vnpy/component/cta_grid_trade.py b/vnpy/component/cta_grid_trade.py index 78688da4..012ba37e 100644 --- a/vnpy/component/cta_grid_trade.py +++ b/vnpy/component/cta_grid_trade.py @@ -854,6 +854,18 @@ class CtaGridTrade(CtaComponent): except Exception: pass + def to_json(self): + data = {} + up_grids = [] + for grid in self.up_grids: + up_grids.append(grid.to_json()) + dn_grids = [] + for grid in self.dn_grids: + dn_grids.append(grid.to_json()) + data[u'up_grids'] = up_grids + data[u'dn_grids'] = dn_grids + return data + def save(self, **kwargs): """ 保存网格至本地Json文件 @@ -879,15 +891,7 @@ class CtaGridTrade(CtaComponent): grid_json_file = str(grids_save_path.joinpath(u'{}_Grids.json'.format(self.json_name))) self.json_file_path = grid_json_file - data = {} - up_grids = [] - for grid in self.up_grids: - up_grids.append(grid.to_json()) - dn_grids = [] - for grid in self.dn_grids: - dn_grids.append(grid.to_json()) - data[u'up_grids'] = up_grids - data[u'dn_grids'] = dn_grids + data = self.to_json() with open(grid_json_file, 'w', encoding='utf8') as f: json_data = json.dumps(data, indent=4, ensure_ascii=False) diff --git a/vnpy/data/tdx/tdx_common.py b/vnpy/data/tdx/tdx_common.py index 88eb0c10..496b2abd 100644 --- a/vnpy/data/tdx/tdx_common.py +++ b/vnpy/data/tdx/tdx_common.py @@ -66,21 +66,21 @@ PERIOD_MAPPING['1month'] = 6 # 期货行情服务器清单 TDX_FUTURE_HOSTS =[ - #{'ip': '42.193.151.197', 'port': 7727, 'name': '广州期货双线1', 'speed': 6.622}, - #{'ip': '119.29.63.178', 'port': 7727, 'name': '广州期货双线3', 'speed': 7.716}, - #{'ip': '81.71.76.101', 'port': 7727, 'name': '广州期货双线2', 'speed': 14.914}, - #{'ip': '47.107.75.159', 'port': 7727, 'name': '扩展市场深圳双线3', 'speed': 34.542}, - #{'ip': '112.74.214.43', 'port': 7727, 'name': '扩展市场深圳双线1', 'speed': 37.881}, - #{'ip': '59.175.238.38', 'port': 7727, 'name': '扩展市场武汉主站3', 'speed': 49.63}, - #{'ip': '119.97.185.5', 'port': 7727, 'name': '扩展市场武汉主站1', 'speed': 70.563}, + {'ip': '42.193.151.197', 'port': 7727, 'name': '广州期货双线1', 'speed': 6.622}, + {'ip': '119.29.63.178', 'port': 7727, 'name': '广州期货双线3', 'speed': 7.716}, + {'ip': '81.71.76.101', 'port': 7727, 'name': '广州期货双线2', 'speed': 14.914}, + {'ip': '47.107.75.159', 'port': 7727, 'name': '扩展市场深圳双线3', 'speed': 34.542}, + {'ip': '112.74.214.43', 'port': 7727, 'name': '扩展市场深圳双线1', 'speed': 37.881}, + {'ip': '59.175.238.38', 'port': 7727, 'name': '扩展市场武汉主站3', 'speed': 49.63}, + {'ip': '119.97.185.5', 'port': 7727, 'name': '扩展市场武汉主站1', 'speed': 70.563}, {'ip': '218.80.248.229', 'port': 7721, 'name': '备用服务器1', 'speed': 86.91300000000001}, - #{'ip': '119.97.185.7', 'port': 7727, 'name': '港股期货武汉主站1', 'speed': 101.06099999999999}, - #{'ip': '106.14.95.149', 'port': 7727, 'name': '扩展市场上海双线', 'speed': 105.294}, + {'ip': '119.97.185.7', 'port': 7727, 'name': '港股期货武汉主站1', 'speed': 101.06099999999999}, + {'ip': '106.14.95.149', 'port': 7727, 'name': '扩展市场上海双线', 'speed': 105.294}, {'ip': '113.105.142.136', 'port': 443, 'name': '扩展市场东莞主站', 'speed': 10000.0}, {'ip': '113.105.142.133', 'port': 443, 'name': '港股期货东莞电信', 'speed': 10000.0}, - #{'ip': '119.97.185.9', 'port': 7727, 'name': '港股期货武汉主站2', 'speed': 10000.0}, + {'ip': '119.97.185.9', 'port': 7727, 'name': '港股期货武汉主站2', 'speed': 10000.0}, {'ip': '202.103.36.71', 'port': 443, 'name': '扩展市场武汉主站2', 'speed': 10000.0}, - #{'ip': '47.92.127.181', 'port': 7727, 'name': '扩展市场北京主站', 'speed': 10000.0}, + {'ip': '47.92.127.181', 'port': 7727, 'name': '扩展市场北京主站', 'speed': 10000.0}, {'ip': '124.74.236.94', 'port': 7721, 'name': '备用服务器2', 'speed': 10000.0}, {'ip': '58.246.109.27', 'port': 7721, 'name': '备用服务器3', 'speed': 10000.0} ] diff --git a/vnpy/gateway/ctp/ctp_gateway.py b/vnpy/gateway/ctp/ctp_gateway.py index 180e3f41..e73016d0 100644 --- a/vnpy/gateway/ctp/ctp_gateway.py +++ b/vnpy/gateway/ctp/ctp_gateway.py @@ -494,7 +494,7 @@ class CtpGateway(BaseGateway): self.l2_md_api.subscribe(req) else: - self.write_log(f'使用CTP接口订阅{req.symbol}') + #self.write_log(f'使用CTP接口订阅{req.symbol}') self.md_api.subscribe(req) # Allow the strategies to start before the connection @@ -822,7 +822,8 @@ class CtpMdApi(MdApi): """ Subscribe to tick data update. """ - self.gateway.write_log(f'{self.name}订阅:{req.exchange} {req.symbol}') + if req.symbol not in self.subscribed: + self.gateway.write_log(f'{self.name}订阅:{req.exchange} {req.symbol}') if self.login_status: self.subscribeMarketData(req.symbol) self.subscribed.add(req.symbol) diff --git a/vnpy/task/celery_app.py b/vnpy/task/celery_app.py index 4161f153..d6956190 100644 --- a/vnpy/task/celery_app.py +++ b/vnpy/task/celery_app.py @@ -31,13 +31,25 @@ celery_config = load_json(file_path) # broker = celery_config.get('celery_broker','redis://192.168.0.202:6379') # backend = celery_config.get('celery_backend','redis://192.168.0.202:6379/0') +# 使用 mongodb +# 配置格式mongodb://userid:password@hostname:port/database_name +# broker = celery_config.get('celery_broker','mongodb://localhost:27017/database_name') + +# celery 6.0+ 通过环境变量配置,没有作为参数传递到Celery()方法中 +# result_backend = celery_config.get('result_backend','mongodb://localhost:27017/') +# mongodb_backend_settings = celery_config.get('mongodb_backend_settings',{ +# 'database': 'mydb', +# 'taskmeta_collection': 'my_taskmeta_collection', +# }) +# backend = None + # 使用rabbitMQ broker = celery_config.get('celery_broker', 'amqp://admin:admin@192.168.0.202:5672//') backend = celery_config.get('celery_backend', 'amqp://admin:admin@192.168.0.202:5672//') print(u'Celery 使用redis配置:\nbroker:{}\nbackend:{}'.format(broker, backend)) -app = Celery('vnpy_task', broker=broker) +app = Celery('vnpy_task', broker=broker, backend=backend) # 动态导入task目录下子任务 # app.conf.CELERY_IMPORTS = ['vnpy.task.celery_app.worker_started'] diff --git a/vnpy/trader/constant.py b/vnpy/trader/constant.py index 2172fc3b..cd6de929 100644 --- a/vnpy/trader/constant.py +++ b/vnpy/trader/constant.py @@ -175,3 +175,145 @@ class StockType(Enum): ETF = 'etf_cn' # ETF CB = 'cb_cn' # 可转债 UNDEFINED = 'undefined' # 未定义 + + +class ChanSignals(Enum): + """ + 缠论信号 + 来源:https://github.com/zengbin93/czsc + """ + Other = "Other~其他" + Y = "Y~是" + N = "N~否" + + INB = "INB~向下笔买点区间" + INS = "INS~向上笔卖点区间" + + FXB = "FXB~向下笔结束分型左侧高点升破" + FXS = "FXS~向上笔结束分型左侧低点跌破" + + BU0 = "BU0~向上笔顶分完成" + BU1 = "BU1~向上笔走势延伸" + + BD0 = "BD0~向下笔底分完成" + BD1 = "BD1~向下笔走势延伸" + + # TK = Triple K + TK1 = "TK1~三K底分" + TK2 = "TK2~三K上涨" + TK3 = "TK3~三K顶分" + TK4 = "TK4~三K下跌" + + # ================================================================================================================== + # 信号值编码规则: + # 多空:L - 多头信号;S - 空头信号; + # 编号:A0 - A类基础型;A1 - A类变种1 ... 以此类推;基础型有着特殊含义,用于因子组合,各种变种形态编号主要用于形态对比研究。 + # 组合规则:笔数_多空_编号;如 LA0 表示多头信号A0 + # ================================================================================================================== + LA0 = "LA0~底背驰" + LB0 = "LB0~双重底背驰" + LG0 = "LG0~上颈线突破" + LH0 = "LH0~向上中枢完成" + LI0 = "LI0~三买" + LJ0 = "LJ0~向上三角扩张中枢" + LK0 = "LK0~向上三角收敛中枢" + LL0 = "LL0~向上平台型中枢" + # ------------------------------------------------------------------------------------------------------------------ + + LA1 = "LA1~底背驰特例一" + LA2 = "LA2~底背驰特例二" + LA3 = "LA3~底背驰特例三" + + LB1 = "LB1~双重底背驰特例一" + LB2 = "LB2~双重底背驰特例二" + LB3 = "LB3~双重底背驰特例三" + + LG1 = "LG1~上颈线突破特例一" + LG2 = "LG2~上颈线突破特例二" + LG3 = "LG3~上颈线突破特例三" + + LH1 = "LH1~向上中枢完成特例一" + LH2 = "LH2~向上中枢完成特例二" + LH3 = "LH3~向上中枢完成特例三" + + LI1 = "LI1~三买特例一" + LI2 = "LI2~三买特例二" + LI3 = "LI3~三买特例三" + + LJ1 = "LJ1~向上三角扩张中枢特例一" + LJ2 = "LJ2~向上三角扩张中枢特例二" + LJ3 = "LJ3~向上三角扩张中枢特例三" + + LK1 = "LK1~向上三角收敛中枢特例一" + LK2 = "LK2~向上三角收敛中枢特例二" + LK3 = "LK3~向上三角收敛中枢特例三" + + LL1 = "LL1~向上平台型中枢特例一" + LL2 = "LL2~向上平台型中枢特例二" + LL3 = "LL3~向上平台型中枢特例三" + + # ------------------------------------------------------------------------------------------------------------------ + SA0 = "SA0~顶背驰" + SB0 = "SB0~双重顶背驰" + SG0 = "SG0~下颈线突破" + SH0 = "SH0~向下中枢完成" + SI0 = "SI0~三卖" + SJ0 = "SJ0~向下三角扩张中枢" + SK0 = "SK0~向下三角收敛中枢" + SL0 = "SL0~向下平台型中枢" + # ------------------------------------------------------------------------------------------------------------------ + SA1 = "SA1~顶背驰特例一" + SA2 = "SA2~顶背驰特例二" + SA3 = "SA3~顶背驰特例三" + + SB1 = "SB1~双重顶背驰特例一" + SB2 = "SB2~双重顶背驰特例二" + SB3 = "SB3~双重顶背驰特例三" + + SG1 = "SG1~下颈线突破特例一" + SG2 = "SG2~下颈线突破特例二" + SG3 = "SG3~下颈线突破特例三" + + SH1 = "SH1~向下中枢完成特例一" + SH2 = "SH2~向下中枢完成特例二" + SH3 = "SH3~向下中枢完成特例三" + + SI1 = "SI1~三卖特例一" + SI2 = "SI2~三卖特例二" + SI3 = "SI3~三卖特例三" + + SJ1 = "SJ1~向下三角扩张中枢特例一" + SJ2 = "SJ2~向下三角扩张中枢特例二" + SJ3 = "SJ3~向下三角扩张中枢特例三" + + SK1 = "SK1~向下三角收敛中枢特例一" + SK2 = "SK2~向下三角收敛中枢特例二" + SK3 = "SK3~向下三角收敛中枢特例三" + + SL1 = "SL1~向下平台型中枢特例一" + SL2 = "SL2~向下平台型中枢特例二" + SL3 = "SL3~向下平台型中枢特例三" + + # -------------------------------------------------------------------------------------------- + # 信号值编码规则: + # 笔数:X3 - 三笔信号; + # 多空:L - 多头信号;S - 空头信号; + # 编号:A0 - A类基础型;A1 - A类变种1 ... 以此类推 + # 组合规则:笔数_多空_编号;如 X3LA0 表示三笔多头信号A0 + # ============================================================================================ + # 三笔形态信号 + # -------------------------------------------------------------------------------------------- + X3LA0 = "X3LA0~向下不重合" + X3LB0 = "X3LB0~向下奔走型中枢" + X3LC0 = "X3LC0~向下三角收敛中枢" + X3LD0 = "X3LD0~向下三角扩张中枢" + X3LE0 = "X3LE0~向下盘背中枢" + X3LF0 = "X3LF0~向下无背中枢" + + X3SA0 = "X3SA0~向上不重合" + X3SB0 = "X3SB0~向上奔走型中枢" + X3SC0 = "X3SC0~向上三角收敛中枢" + X3SD0 = "X3SD0~向上三角扩张中枢" + X3SE0 = "X3SE0~向上盘背中枢" + X3SF0 = "X3SF0~向上无背中枢" + diff --git a/vnpy/trader/utility.py b/vnpy/trader/utility.py index 83d4f47f..c371d1e5 100644 --- a/vnpy/trader/utility.py +++ b/vnpy/trader/utility.py @@ -82,7 +82,12 @@ def get_underlying_symbol(symbol: str): @lru_cache() def get_stock_exchange(code, vn=True): - """根据股票代码,获取交易所""" + """ + 根据股票代码,获取交易所 + :param code: + :param vn: 返回vnpy的交易所格式;False: 返回ricequant的交易所格式 + :return: + """ # vn:取EXCHANGE_SSE 和 EXCHANGE_SZSE code = str(code) if len(code) < 6: