target_pos = dict_target_pos[SYMBOL] update_quote_chan = dict_update_quote_chan[SYMBOL] while True: target_pos_value = 0 async for _ in update_quote_chan: pos_value = position['volume_long'] - position['volume_short'] if (pos_value > 0 and quote["last_price"] - position["open_price_long"] >= 2) or \ (pos_value < 0 and (position["open_price_short"] - quote["last_price"]) >= 2): target_pos_value = 0 print(SYMBOL, '止盈平仓', "时间:", quote["datetime"]) break target_pos.set_target_volume(target_pos_value) await update_quote_chan.close() for symbol in ls_symbols: api.create_task(signal_generator(symbol, MACD_adj)) api.create_task(close_win(symbol)) # with closing(api): # try: # while True: # api.wait_update() # except BacktestFinished: # print('----回测结束----') with closing(api): while True: api.wait_update()
def backtest(): #获取命令行参数 parser = argparse.ArgumentParser() parser.add_argument('--source_file') parser.add_argument('--instance_id') parser.add_argument('--instance_file') parser.add_argument('--output_file') args = parser.parse_args() s = TqSim() report_file = open(args.output_file, "a+") logger = logging.getLogger("TQ") logger.setLevel(logging.INFO) logger.addHandler(TqBacktestLogger(s, report_file)) # 加载策略文件 file_path, file_name = os.path.split(args.source_file) sys.path.insert(0, file_path) module_name = file_name[:-3] # 加载或输入参数 param_list = [] try: # 从文件读取参数表 with open(args.instance_file, "rt") as param_file: instance = json.load(param_file) param_list = instance.get("param_list", []) start_date = datetime.date(instance["start_date"] // 10000, instance["start_date"] % 10000 // 100, instance["start_date"] % 100) end_date = datetime.date(instance["end_date"] // 10000, instance["end_date"] % 10000 // 100, instance["end_date"] % 100) except IOError: # 获取用户代码中的参数表 def _fake_api_for_param_list(*args, **kwargs): m = sys.modules[module_name] for k, v in m.__dict__.items(): if k.upper() != k: continue if isinstance(v, datetime.date) or isinstance(v, datetime.time) \ or isinstance(v, int) or isinstance(v, float) or isinstance(v, str): param_list.append([k, v]) raise Exception() tqsdk.TqApi = _fake_api_for_param_list try: __import__(module_name) except ModuleNotFoundError: logger.exception("加载策略文件失败") return except IndentationError: logger.exception("策略文件缩进格式错误") return except Exception as e: pass param_list, start_date, end_date = input_param_backtest(param_list) if param_list is None: return with open(args.instance_file, "wt") as param_file: json.dump( { "instance_id": args.instance_id, "strategy_file_name": args.source_file, "desc": "%04d/%02d/%02d-%04d/%02d/%02d, %s" % (start_date.year, start_date.month, start_date.day, end_date.year, end_date.month, end_date.day, json.dumps(param_list)), "start_date": start_date.year * 10000 + start_date.month * 100 + start_date.day, "end_date": end_date.year * 10000 + end_date.month * 100 + end_date.day, "param_list": param_list, }, param_file) # 开始回测 api = TqApi(s, backtest=TqBacktest(start_dt=start_date, end_dt=end_date)) sys.stdout = PrintWriter(report_file, args.instance_id) try: json.dump( { "aid": "desc", "desc": "%04d/%02d/%02d-%04d/%02d/%02d, %s" % (start_date.year, start_date.month, start_date.day, end_date.year, end_date.month, end_date.day, json.dumps(param_list)), "start_date": start_date.year * 10000 + start_date.month * 100 + start_date.day, "end_date": end_date.year * 10000 + end_date.month * 100 + end_date.day, "param_list": param_list, }, report_file) report_file.write("\n") api.create_task(account_watcher(api, s, report_file)) try: def _fake_api_for_launch(*args, **kwargs): m = sys.modules[module_name] for k, v in param_list: m.__dict__[k] = v return api tqsdk.TqApi = _fake_api_for_launch __import__(module_name) except tqsdk.exceptions.BacktestFinished: logger.info("策略回测结束") except Exception as e: logger.exception("策略执行中遇到异常", exc_info=True) finally: if not api.loop.is_closed(): api.close()
print(SYMBOL, k15) await update_kline_chan.close() async def signal_generator2(SYMBOL): """该task在价格触发开仓价时开仓,触发平仓价时平仓""" klines = dict_klines[SYMBOL] quote = dict_quotes[SYMBOL] position = dict_positions[SYMBOL] target_pos = dict_target_pos[SYMBOL] # update_quote_chan = dict_update_quote_chan[SYMBOL] # update_kline_chan = dict_update_kline_chan[SYMBOL] async with dict_update_kline_chan[SYMBOL] as update_kline_chan: while True: async for _ in update_kline_chan: if api.is_changing(klines[-1], 'datetime'): k15 = str(dt.datetime.fromtimestamp(klines.datetime[-2] / 1e9) + pd.Timedelta(minutes=2, seconds=59)) ys = pd.Series(data=klines.close[-100:-1], index=[str(dt.datetime.fromtimestamp(i / 1e9)) for i in klines.datetime[-100:-1]] ) print(SYMBOL, '信号时间', k15) for symbol in ls_symbols: api.create_task(signal_generator2(symbol)) with closing(api): try: while True: api.wait_update() except BacktestFinished: print('Backtest end')
target_pos = TargetPosTask(api, symbol) target_volume = 0 # 目标持仓手数 async def price_watcher(open_price, close_price, volume): """该task在价格触发开仓价时开仓,触发平仓价时平仓""" global target_volume async with api.register_update_notify(quote) as update_chan: # 当 quote 有更新时会发送通知到 update_chan 上 while True: async for _ in update_chan: # 当从 update_chan 上收到行情更新通知时判断是否触发开仓条件 if (volume > 0 and quote.last_price <= open_price) or (volume < 0 and quote.last_price >= open_price): break target_volume += volume target_pos.set_target_volume(target_volume) print("时间:", quote.datetime, "最新价:", quote.last_price, "开仓", volume, "手", "总仓位:", target_volume, "手") async for _ in update_chan: # 当从 update_chan 上收到行情更新通知时判断是否触发平仓条件 if (volume > 0 and quote.last_price > close_price) or (volume < 0 and quote.last_price < close_price): break target_volume -= volume target_pos.set_target_volume(target_volume) print("时间:", quote.datetime, "最新价:", quote.last_price, "平仓", volume, "手", "总仓位:", target_volume, "手") for i in range(grid_amount): api.create_task(price_watcher(grid_prices_long[i+1], grid_prices_long[i], grid_volume_long[i])) api.create_task(price_watcher(grid_prices_short[i+1], grid_prices_short[i], grid_volume_short[i])) with closing(api): while True: api.wait_update()
async for _ in update_price_chan: # 当从 update_chan 上收到行情更新通知时判断是否触发开仓条件 ys = pd.Series(data=klines.close[-100:-1], index=[ str(dt.datetime.fromtimestamp(i / 1e9)) for i in klines.datetime[-100:-1] ]) target_pos.set_target_volume(1) print(SYMBOL, '价格') async def position_watcher(SYMBOL): quote = api.get_quote(SYMBOL) position = api.get_position(SYMBOL) async with api.register_update_notify(quote) as update_quote_chan: while True: async for _ in update_quote_chan: pos = position['volume_long'] - position['volume_short'] print(SYMBOL, '持仓', pos) for symbol in ls_symbol: api.create_task(price_watcher(symbol)) api.create_task(position_watcher(symbol)) with closing(api): try: while True: api.wait_update() except BacktestFinished: print('Backtest end')
for i in klines.datetime[-250:-1] ]) dict_Patterns, Peaks, Bottoms = HS(ys, pflag=0, method='RW', w=3, iteration=0) print(dict_Patterns) HS_plotting(ys, Peaks, Bottoms, dict_Patterns, figname='hanyi//ni' + str_name, savefig=True) await update_kline_chan.close() for SYMBOL in ls_symbols: api.create_task(signal_generator_HS(SYMBOL)) # with closing(api): # try: # while True: # api.wait_update() # except BacktestFinished: # print('----回测结束----') with closing(api): while True: api.wait_update()
target_pos.set_target_volume(target_pos_value) await update_kline_chan.close() async def close_win(SYMBOL): update_quote_chan = api.register_update_notify( quote) # 当 quote 有更新时会发送通知到 update_chan 上 while True: async for _ in update_quote_chan: target_pos_value = position["volume_long"] - position[ "volume_short"] # 净目标净持仓数 if (target_pos_value > 0 and quote["last_price"] - position["open_price_long"] >= 1) or\ (target_pos_value < 0 and (position["open_price_short"] - quote["last_price"]) >= 1): target_pos_value = 0 print('止盈平仓') break target_pos.set_target_volume(target_pos_value) await update_quote_chan.close() api.create_task(signal_generator(SYMBOL)) api.create_task(close_win(SYMBOL)) with closing(api): try: while True: api.wait_update() except BacktestFinished: print('Backtest end')
def init_turtle(api: TqApi, s: pd.Series): api.create_task(coroutine_turtle(api, s['quote_inst'])) return
async def close_win(SYMBOL): """该task应用策略在价格触发止盈条件时平仓""" quote = api.get_quote(SYMBOL) position = api.get_position(SYMBOL) target_pos = TargetPosTask(api, SYMBOL) async with api.register_update_notify(quote) as update_quote_chan: while True: async for _ in update_quote_chan: target_pos = TargetPosTask(api, SYMBOL) target_pos_value = position['volume_long'] - position[ 'volume_short'] print(SYMBOL, target_pos_value, "时间:", quote["datetime"]) if (target_pos_value > 0 and quote["last_price"] - position["open_price_long"] >= 2) or \ (target_pos_value < 0 and (position["open_price_short"] - quote["last_price"]) >= 2): target_pos.set_target_volume(0) print(SYMBOL, '止盈平仓') for symbol in ls_symbols: api.create_task(signal_generator(symbol, talib.MACD)) api.create_task(close_win(symbol)) with closing(api): try: while True: api.wait_update() except BacktestFinished: print('----回测结束----')
if event is None or event == 'Exit': sys.exit(0) # 更新界面数据 window.Element('datetime').Update(quote_future.datetime[:19]) window.Element('spot.last').Update('nan' if math.isnan( quote_spot.last_price) else int(quote_spot.last_price)) window.Element('future.last').Update('nan' if math.isnan( quote_future.last_price) else int(quote_future.last_price)) future_change = (quote_future.last_price - quote_future.pre_settlement ) / quote_future.pre_settlement * 100 if math.isnan(future_change): window.Element('future.change').Update("(nan)", text_color="black") else: window.Element('future.change').Update( "({}%)".format(round(future_change, 2)), text_color="red" if future_change >= 0 else "green") spread = quote_future.last_price - quote_spot.last_price window.Element('spread').Update( 'nan' if math.isnan(spread) else int(spread)) await asyncio.sleep(0.001) # 注意, 这里必须使用 asyncio.sleep, 不能用time.sleep api.create_task(gui_task()) # ------------------------------- TqApi Task Code ----------------------- while True: api.wait_update()
def backtest(): #获取命令行参数 parser = argparse.ArgumentParser() parser.add_argument('--source_file') parser.add_argument('--instance_id') parser.add_argument('--instance_file') parser.add_argument('--output_file') args = parser.parse_args() s = TqSim() out = open(args.output_file, "a+") logger = logging.getLogger("TQ") logger.setLevel(logging.INFO) logger.addHandler(TqBacktestLogger(s, out)) # 加载策略文件 file_path, file_name = os.path.split(args.source_file) sys.path.insert(0, file_path) module_name = file_name[:-3] # 加载或输入参数 param_list = [] try: # 从文件读取参数表 with open(args.instance_file, "rt") as param_file: instance = json.load(param_file) param_list = instance.get("param_list", []) start_date = datetime.date(instance["start_date"] // 10000, instance["start_date"] % 10000 // 100, instance["start_date"] % 100) end_date = datetime.date(instance["end_date"] // 10000, instance["end_date"] % 10000 // 100, instance["end_date"] % 100) except IOError: # 获取用户代码中的参数表 def _fake_api_for_param_list(*args, **kwargs): m = sys.modules[module_name] for k, v in m.__dict__.items(): if k.upper() != k: continue param_list.append([k, v]) raise Exception() tqsdk.TqApi = _fake_api_for_param_list try: importlib.import_module(module_name) except ModuleNotFoundError: logger.exception("加载策略文件失败") except IndentationError: logger.exception("策略文件缩进格式错误") except Exception as e: pass param_list, start_date, end_date = input_param_backtest(param_list) if param_list is None: return with open(args.instance_file, "wt") as param_file: json.dump( { "instance_id": args.instance_id, "strategy_file_name": args.source_file, "desc": json.dumps(param_list), "start_date": start_date.year * 10000 + start_date.month * 100 + start_date.day, "end_date": end_date.year * 10000 + end_date.month * 100 + end_date.day, "param_list": param_list, }, param_file) # 开始回测 api = TqApi(s, backtest=TqBacktest(start_dt=start_date, end_dt=end_date)) with closing(api): api.send_chan.send_nowait({ "aid": "status", "instance_id": args.instance_id, "status": "RUNNING", "desc": json.dumps(param_list) }) api.create_task(account_watcher(api, s, out)) try: def _fake_api_for_launch(*args, **kwargs): m = sys.modules[module_name] for k, v in param_list: m.__dict__[k] = v return api tqsdk.TqApi = _fake_api_for_launch importlib.import_module(module_name) except ModuleNotFoundError: logger.exception("加载策略文件失败") except IndentationError: logger.exception("策略文件缩进格式错误") except tqsdk.exceptions.BacktestFinished: logger.info("策略回测结束") except Exception as e: logger.exception("策略执行中遇到异常", exc_info=True)