def test_lib_insert_order_time_check_1(self): """ lib下单时间判断测试1 回测时间: 周一21:00 - 周二10:00 合约订阅: 无夜盘; 有夜盘24:00结束; 有夜盘25:00结束 测试: 21:00起始时刻两个有夜盘合约立即下單,无夜盘合约第二日白盘下单; 23:00某一夜盘合约停止交易后不能下單,另一合约能下單; """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_lib_insert_order_time_check_1.script.lzma")) TqApi.RD = random.Random(4) api = TqApi(backtest=TqBacktest( datetime.datetime(2019, 12, 2, 21, 0, 0), datetime.datetime(2019, 12, 3, 10, 0, 0)), _ins_url=self.ins_url_2019_12_04) # 2019.12.2周一 symbol1 = "DCE.jd2002" # 无夜盘 symbol2 = "SHFE.rb2002" # 夜盘23点结束 symbol3 = "SHFE.cu2002" # 夜盘凌晨1点结束 quote3 = api.get_quote(symbol3) target_pos1 = TargetPosTask(api, symbol1) target_pos2 = TargetPosTask(api, symbol2) target_pos3 = TargetPosTask(api, symbol3) position1 = api.get_position(symbol1) position2 = api.get_position(symbol2) position3 = api.get_position(symbol3) orders = api.get_order() try: # 1 21:00起始时刻有夜盘合约立即下單,无夜盘合约第二日白盘下单; target_pos1.set_target_volume(1) target_pos2.set_target_volume(2) target_pos3.set_target_volume(3) while datetime.datetime.strptime( quote3.datetime, "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime( 2019, 12, 2, 21, 2): api.wait_update() self.assertEqual(len(orders), 2) self.assertEqual(position1.pos, 0) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 3) # 2 23:00某一夜盘合约停止交易后不能下單,另一合约能下單; while datetime.datetime.strptime( quote3.datetime, "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime( 2019, 12, 3, 0, 0): api.wait_update() target_pos1.set_target_volume(4) target_pos2.set_target_volume(5) target_pos3.set_target_volume(6) while datetime.datetime.strptime( quote3.datetime, "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime( 2019, 12, 3, 0, 30): api.wait_update() self.assertEqual(len(orders), 3) self.assertEqual(position1.pos, 0) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 6) while True: api.wait_update() except BacktestFinished: # 验证下單情況 # 第二个交易日白盘,将所有合约调整到目标手数 self.assertEqual(len(orders), 5) self.assertEqual(position1.pos, 4) self.assertEqual(position2.pos, 5) self.assertEqual(position3.pos, 6) print("回测结束") api.close()
trading_date = '' parser = argparse.ArgumentParser() parser.add_argument('--SYMBOL') args = parser.parse_args() if args.SYMBOL != None: SYMBOL = args.SYMBOL else: SYMBOL = "DCE.i2005" #STEP2:策略执行log logger.info("Starting xiadiyu strategy for: %s"%SYMBOL) api = TqApi(TqSim()) klines = api.get_kline_serial(SYMBOL, duration_seconds=60*60*24, data_length=20) #ticks = api.get_tick_serial(SYMBOL) quote = api.get_quote(SYMBOL) while True: api.wait_update() # 跟踪log信息,日k数据会产生两个信号:一个是开盘时,另一个时收盘;如果想根据收盘k线分析前期趋势,用第二个信号 # 这样就没有之前认为必须开盘才能分析之前所存在的趋势型机会了。 # 实盘是只要14:59或盘后任何时间触发运行即可,一次退出; # 想尾盘参与策略型机会则收盘前运行回报策略型机会,次日择机参与则盘后任何时间运行即可 if api.is_changing(klines): df = klines.to_dataframe() #logger.info("DATE: %s, close: %f"%(bases.get_market_day(klines[-1]["datetime"]), klines[-1]["close"]))
from datetime import date import datetime from tqsdk import TqApi, TqBacktest, TargetPosTask, TqSim import pandas as pd import os import time import gc buying_prob = 0.8 selling_prob = 0.2 acc = TqSim(init_balance=1000000) start_date = date(2019, 9, 1) end_date = date(2020, 4, 20) # 在创建 api 实例时传入 TqBacktest 就会进入回测模式 api = TqApi(acc, backtest=TqBacktest(start_dt=start_date, end_dt=end_date), web_gui='127.0.0.1:9999') base_path = 'data' pred = pd.read_csv(os.path.join(base_path, 'result.csv')) pred = pred.sort_values('datetime').reset_index(drop=True) pred['datetime'] = pd.to_datetime(pred['datetime'], infer_datetime_format=True) pred['datetime_open'] = pd.to_datetime(pred['datetime_open'], infer_datetime_format=True) pred['datetime_close'] = pd.to_datetime(pred['datetime_close'], infer_datetime_format=True) pred = pred[(pred['pred'] > buying_prob) | (pred['pred'] < selling_prob)].reset_index(drop=True) # pred['is_sc'] = pred['ts_code'].apply(lambda x:True if 'sc' in x else False) # pred = pred[pred['is_sc'] == False].reset_index()
def test_insert_order_option(self): """ 期权下单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join( dir_path, "log_file", "test_td_basic_insert_order_simulate_option.script.lzma")) # 测试: 模拟账户下单 # 非回测, 则需在盘中生成测试脚本: 测试脚本重新生成后,数据根据实际情况有变化,因此需要修改assert语句的内容 TqApi.RD = random.Random(2) api = TqApi(_ins_url=self.ins_url_2020_04_02, _td_url=self.td_url, _md_url=self.md_url) order1 = api.insert_order("SHFE.cu2006C47000", "BUY", "OPEN", 1, limit_price=135) order2 = api.insert_order("CZCE.SR007C5600", "SELL", "OPEN", 2, limit_price=30) order3 = api.insert_order("DCE.m2007-P-2900", "BUY", "OPEN", 3, limit_price=192) while order1.status == "ALIVE" or order2.status == "ALIVE" or order3.status == "ALIVE": api.wait_update() self.assertEqual(order1.order_id, "5c6e433715ba2bdd177219d30e7a269f") self.assertEqual(order1.direction, "BUY") self.assertEqual(order1.offset, "OPEN") self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order1.limit_price, 135.0) self.assertEqual(order1.price_type, "LIMIT") self.assertEqual(order1.volume_condition, "ANY") self.assertEqual(order1.time_condition, "GFD") self.assertAlmostEqual(1586829882005334000 / 1e9, order1.insert_date_time / 1e9, places=1) self.assertEqual(order1.status, "FINISHED") for k, v in order1.trade_records.items(): # 模拟交易为一次性全部成交,因此只有一条成交记录 self.assertAlmostEqual(1586829882005979000 / 1e9, v.trade_date_time / 1e9, places=1) del v.trade_date_time self.assertEqual( str(v), "{'order_id': '5c6e433715ba2bdd177219d30e7a269f', 'trade_id': '5c6e433715ba2bdd177219d30e7a269f|1', 'exchange_trade_id': '5c6e433715ba2bdd177219d30e7a269f|1', 'exchange_id': 'SHFE', 'instrument_id': 'cu2006C47000', 'direction': 'BUY', 'offset': 'OPEN', 'price': 135.0, 'volume': 1, 'user_id': 'TQSIM', 'commission': 10}" ) self.assertEqual(order2.order_id, "cf1822ffbc6887782b491044d5e34124") self.assertEqual(order2.direction, "SELL") self.assertEqual(order2.offset, "OPEN") self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order2.limit_price, 30.0) self.assertEqual(order2.price_type, "LIMIT") self.assertEqual(order2.volume_condition, "ANY") self.assertEqual(order2.time_condition, "GFD") self.assertAlmostEqual(1586829882236154000 / 1e9, order2.insert_date_time / 1e9, places=1) self.assertEqual(order2.status, "FINISHED") for k, v in order2.trade_records.items(): # 模拟交易为一次性全部成交,因此只有一条成交记录 self.assertAlmostEqual(1586829882236518000 / 1e9, v.trade_date_time / 1e9, places=1) del v.trade_date_time self.assertEqual( str(v), "{'order_id': 'cf1822ffbc6887782b491044d5e34124', 'trade_id': 'cf1822ffbc6887782b491044d5e34124|2', 'exchange_trade_id': 'cf1822ffbc6887782b491044d5e34124|2', 'exchange_id': 'CZCE', 'instrument_id': 'SR007C5600', 'direction': 'SELL', 'offset': 'OPEN', 'price': 30.0, 'volume': 2, 'user_id': 'TQSIM', 'commission': 20}" ) self.assertEqual(order3.order_id, "4067c3584ee207f8da94e3e8ab73738f") self.assertEqual(order3.direction, "BUY") self.assertEqual(order3.offset, "OPEN") self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(order3.limit_price, 192.0) self.assertEqual(order3.price_type, "LIMIT") self.assertEqual(order3.volume_condition, "ANY") self.assertEqual(order3.time_condition, "GFD") self.assertAlmostEqual(1586829882228039000 / 1e9, order3.insert_date_time / 1e9, places=1) self.assertEqual(order3.status, "FINISHED") for k, v in order3.trade_records.items(): # 模拟交易为一次性全部成交,因此只有一条成交记录 self.assertAlmostEqual(1586829882228603000 / 1e9, v.trade_date_time / 1e9, places=1) del v.trade_date_time self.assertEqual( str(v), "{'order_id': '4067c3584ee207f8da94e3e8ab73738f', 'trade_id': '4067c3584ee207f8da94e3e8ab73738f|3', 'exchange_trade_id': '4067c3584ee207f8da94e3e8ab73738f|3', 'exchange_id': 'DCE', 'instrument_id': 'm2007-P-2900', 'direction': 'BUY', 'offset': 'OPEN', 'price': 192.0, 'volume': 3, 'user_id': 'TQSIM', 'commission': 30}" ) api.close()
def test_get_position_option(self): """ 获取持仓 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join( dir_path, "log_file", "test_td_basic_get_position_simulate_option.script.lzma")) # 测试: 获取数据 api = TqApi(_ins_url=self.ins_url_2020_04_02, _td_url=self.td_url, _md_url=self.md_url) order1 = api.insert_order("CZCE.SR007C5600", "BUY", "OPEN", 2, limit_price=55) order2 = api.insert_order("CZCE.SR007C5600", "BUY", "OPEN", 3, limit_price=55) order3 = api.insert_order("CZCE.SR007C5600", "SELL", "OPEN", 3, limit_price=52) order4 = api.insert_order("CZCE.SR007C5600", "SELL", "OPEN", 3) while order1.status == "ALIVE" or order2.status == "ALIVE" or order3.status == "ALIVE" or order4.status == "ALIVE": api.wait_update() self.assertEqual(order4.volume_left, 3) position = api.get_position("CZCE.SR007C5600") # 测试脚本重新生成后,数据根据实际情况有变化 self.assertEqual( "{'exchange_id': 'CZCE', 'instrument_id': 'SR007C5600', 'pos_long_his': 0, 'pos_long_today': 5, 'pos_short_his': 0, 'pos_short_today': 3, 'volume_long_today': 5, 'volume_long_his': 0, 'volume_long': 5, 'volume_long_frozen_today': 0, 'volume_long_frozen_his': 0, 'volume_long_frozen': 0, 'volume_short_today': 3, 'volume_short_his': 0, 'volume_short': 3, 'volume_short_frozen_today': 0, 'volume_short_frozen_his': 0, 'volume_short_frozen': 0, 'open_price_long': 55.0, 'open_price_short': 52.0, 'open_cost_long': 2750.0, 'open_cost_short': 1560.0, 'position_price_long': 55.0, 'position_price_short': 52.0, 'position_cost_long': 2750.0, 'position_cost_short': 1560.0, 'float_profit_long': -100.0, 'float_profit_short': -30.0, 'float_profit': -130.0, 'position_profit_long': 0.0, 'position_profit_short': 0.0, 'position_profit': 0.0, 'margin_long': 0.0, 'margin_short': 4797.200000000001, 'margin': 4797.200000000001, 'market_value_long': 2650.0, 'market_value_short': -1590.0, 'market_value': 1060.0, 'last_price': 53.0}", str(position)) self.assertEqual(2, position.pos) self.assertEqual(5, position.pos_long) self.assertEqual(3, position.pos_short) self.assertEqual(position.exchange_id, "CZCE") self.assertEqual(position.instrument_id, "SR007C5600") self.assertEqual(position.pos_long_his, 0) self.assertEqual(position.pos_long_today, 5) self.assertEqual(position.pos_short_his, 0) self.assertEqual(position.pos_short_today, 3) self.assertEqual(position.volume_long_today, 5) self.assertEqual(position.volume_long_his, 0) self.assertEqual(position.volume_long, 5) self.assertEqual(position.volume_long_frozen_today, 0) self.assertEqual(position.volume_long_frozen_his, 0) self.assertEqual(position.volume_long_frozen, 0) self.assertEqual(position.volume_short_today, 3) self.assertEqual(position.volume_short_his, 0) self.assertEqual(position.volume_short, 3) self.assertEqual(position.volume_short_frozen_today, 0) self.assertEqual(position.volume_short_frozen_his, 0) self.assertEqual(position.volume_short_frozen, 0) self.assertEqual(position.open_price_long, 55.0) self.assertEqual(position.open_price_short, 52.0) self.assertEqual(position.open_cost_long, 2750.0) self.assertEqual(position.open_cost_short, 1560.0) self.assertEqual(position.position_price_long, 55.0) self.assertEqual(position.position_price_short, 52.0) self.assertEqual(position.position_cost_long, 2750.0) self.assertEqual(position.position_cost_short, 1560.0) self.assertEqual(position.float_profit_long, -100.0) self.assertEqual(position.float_profit_short, -30.0) self.assertEqual(position.float_profit, -130.0) self.assertEqual(position.position_profit_long, 0.0) self.assertEqual(position.position_profit_short, 0.0) self.assertEqual(position.position_profit, 0.0) self.assertEqual(position.margin_long, 0.0) self.assertEqual(position.margin_short, 4797.200000000001) self.assertEqual(position.margin, 4797.200000000001) self.assertEqual(position.market_value_long, 2650.0) self.assertEqual(position.market_value_short, -1590.0) self.assertEqual(position.market_value, 1060.0) self.assertEqual(position.last_price, 53.0) # 其他取值方式测试 self.assertEqual(position["pos_long_today"], 5) self.assertEqual(position["pos_short_today"], 3) self.assertEqual(position["volume_long_his"], 0) self.assertEqual(position["volume_long"], 5) api.close()
def dual_thrust(quote, klines): current_open = quote["open"] HH = max(klines.high[-Nday - 1:-1]) # N日最高价的最高价 HC = max(klines.close[-Nday - 1:-1]) # N日收盘价的最高价 LC = min(klines.close[-Nday - 1:-1]) # N日收盘价的最低价 LL = min(klines.low[-Nday - 1:-1]) # N日最低价的最低价 range = max(HH - LC, HC - LL) buy_line = current_open + range * K1 # 上轨 sell_line = current_open - range * K2 # 下轨 print("当前开盘价:", current_open, "\n上轨:", buy_line, "\n下轨:", sell_line) return buy_line, sell_line api = TqApi(TqSim()) quote = api.get_quote(symbol) klines = api.get_kline_serial(symbol, 24*60*60) # 86400使用日线 target_pos = TargetPosTask(api, symbol) buy_line, sell_line = dual_thrust(quote, klines) # 获取上下轨 while True: api.wait_update() if api.is_changing(klines[-1], "datetime") or api.is_changing(quote, "open"): # 新产生一根日线或开盘价发生变化: 重新计算上下轨 buy_line, sell_line = dual_thrust(quote, klines) if api.is_changing(quote, "last_price"): print("最新价变化", quote["last_price"], end=':') if quote["last_price"] > buy_line: # 高于上轨 print("高于上轨,目标持仓 多头3手") target_pos.set_target_volume(3) # 交易
def test_get_order(self): """ 获取委托单信息 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_td_basic_get_order_simulate.script.lzma")) # 测试: 模拟账户下单 TqApi.RD = random.Random(4) api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) order1 = api.insert_order("DCE.jd2005", "BUY", "OPEN", 1) order2 = api.insert_order("SHFE.cu2005", "SELL", "OPEN", 2, limit_price=40750) while order1.status == "ALIVE" or order2.status == "ALIVE": api.wait_update() get_order1 = api.get_order(order1.order_id) get_order2 = api.get_order(order2.order_id) self.assertEqual(get_order1.order_id, "1710cf5327ac435a7a97c643656412a9") self.assertEqual(get_order1.direction, "BUY") self.assertEqual(get_order1.offset, "OPEN") self.assertEqual(get_order1.volume_orign, 1) self.assertEqual(get_order1.volume_left, 0) self.assertNotEqual(get_order1.limit_price, get_order1.limit_price) # 判断nan self.assertEqual(get_order1.price_type, "ANY") self.assertEqual(get_order1.volume_condition, "ANY") self.assertEqual(get_order1.time_condition, "IOC") # 因为TqSim模拟交易的 insert_date_time 不是固定值,所以改为判断范围(前后100毫秒) self.assertAlmostEqual(1586415071223454000 / 1e9, get_order1.insert_date_time / 1e9, places=1) self.assertEqual(get_order1.last_msg, "全部成交") self.assertEqual(get_order1.status, "FINISHED") self.assertEqual(get_order1.frozen_margin, 0) self.assertEqual(get_order2.order_id, "8ca5996666ceab360512bd1311072231") self.assertEqual(get_order2.direction, "SELL") self.assertEqual(get_order2.offset, "OPEN") self.assertEqual(get_order2.volume_orign, 2) self.assertEqual(get_order2.volume_left, 0) self.assertEqual(get_order2.limit_price, 40750) self.assertEqual(get_order2.price_type, "LIMIT") self.assertEqual(get_order2.volume_condition, "ANY") self.assertEqual(get_order2.time_condition, "GFD") self.assertAlmostEqual(1586415071224110000 / 1e9, get_order2["insert_date_time"] / 1e9, places=1) self.assertEqual(get_order2["last_msg"], "全部成交") self.assertEqual(get_order2["status"], "FINISHED") self.assertEqual(get_order2.frozen_margin, 0) del get_order1["insert_date_time"] del get_order2["insert_date_time"] self.assertEqual( str(get_order1), "{'order_id': '1710cf5327ac435a7a97c643656412a9', 'exchange_order_id': '1710cf5327ac435a7a97c643656412a9', 'exchange_id': 'DCE', 'instrument_id': 'jd2005', 'direction': 'BUY', 'offset': 'OPEN', 'volume_orign': 1, 'volume_left': 0, 'limit_price': nan, 'price_type': 'ANY', 'volume_condition': 'ANY', 'time_condition': 'IOC', 'last_msg': '全部成交', 'status': 'FINISHED', 'user_id': 'TQSIM', 'frozen_margin': 0.0, 'frozen_premium': 0.0}" ) self.assertEqual( str(get_order2), "{'order_id': '8ca5996666ceab360512bd1311072231', 'exchange_order_id': '8ca5996666ceab360512bd1311072231', 'exchange_id': 'SHFE', 'instrument_id': 'cu2005', 'direction': 'SELL', 'offset': 'OPEN', 'volume_orign': 2, 'volume_left': 0, 'limit_price': 40750.0, 'price_type': 'LIMIT', 'volume_condition': 'ANY', 'time_condition': 'GFD', 'last_msg': '全部成交', 'status': 'FINISHED', 'user_id': 'TQSIM', 'frozen_margin': 0.0, 'frozen_premium': 0.0}" ) api.close()
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'limin' from tqsdk import TqApi ''' 画图示例: 在主图中画信号线及文字标注 注意:1 画图功能仅在天勤终端/天勤Vscode插件中生效,请在这两个平台中运行画图相关的代码 2 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改 ''' api = TqApi(web_gui=True) klines = api.get_kline_serial("SHFE.au2002", 60) while True: # 在主图中最后一根K线上画射线以标注需要的信号 api.draw_line(klines, -1, klines.iloc[-1].close, -1, klines.iloc[-1].high, id="my_line", line_type="RAY", color=0xFFFF9900, width=3) # 绘制字符串 api.draw_text(klines, "信号1", x=-1, y=klines.iloc[-1].high + 5, id="my_text",
from tqsdk import TqApi api = TqApi() # 开仓两手并等待完成 order = api.insert_order(symbol="SHFE.rb1901", direction="BUY", offset="OPEN", limit_price=4310, volume=2) while order["status"] != "FINISHED": api.wait_update() print("已开仓") # 平今两手并等待完成 order = api.insert_order(symbol="SHFE.rb1901", direction="SELL", offset="CLOSETODAY", limit_price=3925, volume=2) while order["status"] != "FINISHED": api.wait_update() print("已平今") # 关闭api,释放相应资源 api.close()
# logger.addHandler(mail_handler) logger.setLevel(logging.DEBUG) logger.addHandler(fh) logger.propagate = False # try: if __name__ == '__main__': logger.debug('This is yhlz\'s trading server,now started!\n') # 定义常量 durationTransDict = {'1m': 60, '1d': 86400} try: # api=TqApi(TqAccount('快期模拟','284837','86888196')) api = TqApi(TqAccount('simnow', '133492', 'Yhlz0000'), web_gui=True) logger.info('success sign in! with simnow') # api = TqApi(TqAccount('H华安期货', '100909186', 'Yhlz0000')) # Yhlz.info('success sign in! with 100909186') except Exception as e: logger.info('problem with sign in!') exit(1) f = open('strategytorun.txt') temp = f.readlines() f.close() '---------------------------------------------------初始化数据------------------------------------------------------' strategys = {}
#!/usr/bin/env python # -*- coding: utf-8 -*- from tqsdk import TqApi, TqAccount from otg_check_helper import check_orders, check_positions, check_account, check_risk_rule, check_risk_data, check_all from test_for_etf.base_info import bid, user_id, pwd, td_url, test_logger if __name__ == '__main__': api = TqApi(TqAccount(bid, user_id, pwd), auth="ringo,Shinnytech123", _stock=True, _td_url=td_url) # 触发自成交风控限制 rule = api.set_risk_management_rule("SSE", True, count_limit=0) test_logger.info(f"{'='*12} 期权 开仓 {'='*12}") symbol = "SSE.10002477" quote = api.get_quote(symbol) # ETF 期权 # 挂单 sell_order = api.insert_order(symbol=symbol, direction="SELL", offset="OPEN", limit_price=quote.upper_limit - quote.price_tick, volume=2) api.wait_update() buy_order = api.insert_order(symbol=symbol, direction="BUY", offset="OPEN",
def test_lib_insert_order_time_check_7(self): """ lib下单时间判断测试7 订阅合约: 订阅周六有行情的和周六无行情的 测试: (测试:回测从周六开始时 可交易时间段的计算、判断) 1 回测刚开始:current_datetime 为 0:00 , 只有cu能下单,另外两个合约直到白盘9点下单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_lib_insert_order_time_check_7.script.lzma")) TqApi.RD = random.Random(4) api = TqApi(backtest=TqBacktest( datetime.datetime(2019, 11, 30, 0, 0, 0), datetime.datetime(2019, 12, 2, 9, 30)), _ins_url=self.ins_url_2019_12_04) symbol1 = "SHFE.cu2002" # 有夜盘,凌晨1点结束夜盘 symbol2 = "SHFE.rb2002" # 夜盘23点结束 symbol3 = "DCE.jd2002" # 无夜盘 quote1 = api.get_quote(symbol1) quote2 = api.get_quote(symbol2) quote3 = api.get_quote(symbol3) position1 = api.get_position(symbol1) position2 = api.get_position(symbol2) position3 = api.get_position(symbol3) target_pos1 = TargetPosTask(api, symbol1) target_pos2 = TargetPosTask(api, symbol2) target_pos3 = TargetPosTask(api, symbol3) orders = api.get_order() try: # 1 回测刚开始:current_datetime 为 0:00 , 只有cu能下单,另外两个合约直到白盘9点下单 target_pos1.set_target_volume(1) target_pos2.set_target_volume(2) target_pos3.set_target_volume(3) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-11-30 00:02:00.000000": api.wait_update() self.assertEqual(len(orders), 1) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-11-30 00:15:00.000000": api.wait_update() self.assertEqual(len(orders), 1) self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 0) self.assertEqual(position3.pos, 0) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-02 09:05:00.000000": api.wait_update() self.assertEqual(len(orders), 3) self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 3) while True: api.wait_update() except BacktestFinished: self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 3) api.close()
def test_lib_insert_order_time_check_6(self): ''' lib下单时间判断测试6 测试: 设置目标持仓后在TargetPosTask未下单前调整目标持仓, lib等到10:30有行情之后调整到的是最新目标持仓 ''' # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_lib_insert_order_time_check_6.script.lzma")) TqApi.RD = random.Random(4) api = TqApi(backtest=TqBacktest(start_dt=datetime.datetime( 2019, 7, 11, 10, 15), end_dt=datetime.date(2019, 7, 12)), _ins_url=self.ins_url_2019_12_04) symbol1 = "SHFE.cu1908" symbol2 = "CFFEX.IF1908" # 用于行情推进,到10:20 quote2 = api.get_quote(symbol2) target_pos = TargetPosTask(api, symbol1) orders = api.get_order() position = api.get_position(symbol1) try: target_pos.set_target_volume(5) while quote2.datetime < "2019-07-11 10:20:00.000000": api.wait_update() self.assertEqual(len(api.get_order()), 0) target_pos.set_target_volume(2) while quote2.datetime < "2019-07-11 10:25:00.000000": api.wait_update() self.assertEqual(len(api.get_order()), 0) while True: api.wait_update() except BacktestFinished: self.assertEqual(len(orders), 1) self.assertEqual(position.pos, 2) api.close()
def test_lib_insert_order_time_check_5(self): ''' lib下单时间判断测试5 回测时间: 起始交易日(datetime.date)在非周一 订阅: cu(有夜盘,凌晨1点结束夜盘),rb(夜盘23点结束),jd(无夜盘) 测试: 1 起始回测在21点后rb、cu下单,到第二日9点后jd下单 2 本交易日白盘9:00后jd下单 ''' # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_lib_insert_order_time_check_5.script.lzma")) TqApi.RD = random.Random(4) api = TqApi(backtest=TqBacktest(datetime.date(2019, 12, 3), datetime.date(2019, 12, 4)), _ins_url=self.ins_url_2019_12_04) # 2019, 12, 3:周二 symbol1 = "SHFE.cu2002" # 有夜盘,凌晨1点结束夜盘 symbol2 = "SHFE.rb2002" # 夜盘23点结束 symbol3 = "DCE.jd2002" # 无夜盘 quote1 = api.get_quote(symbol1) quote2 = api.get_quote(symbol2) quote3 = api.get_quote(symbol3) position1 = api.get_position(symbol1) position2 = api.get_position(symbol2) position3 = api.get_position(symbol3) target_pos1 = TargetPosTask(api, symbol1) target_pos2 = TargetPosTask(api, symbol2) target_pos3 = TargetPosTask(api, symbol3) orders = api.get_order() try: # 1 起始回测在21点后rb、cu下单,到第二日9点后jd下单 target_pos1.set_target_volume(1) target_pos2.set_target_volume(2) target_pos3.set_target_volume(3) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-02 21:05:00.000000": api.wait_update() self.assertEqual(len(orders), 2) self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 0) # 2 本交易日白盘9:00后jd下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-03 09:02:00.000000": api.wait_update() self.assertEqual(len(orders), 3) while True: api.wait_update() except BacktestFinished: self.assertEqual(len(orders), 3) self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 3) api.close()
def record_quotes(symbols, _stock, _md_url): api = TqApi(auth=AUTH, _stock=_stock, _md_url=_md_url) api._requests["quotes"] = set(symbols) api._send_chan.send_nowait({ "aid": "subscribe_quote", "ins_list": ",".join(symbols) }) api.wait_update() api.wait_update() quotes = {} csv_files = {} for s in symbols: quotes[s] = api.get_quote(s) csv_files[s] = (create_csvfile(s, "new" if _stock else "old")) csv_files[s][1].writerow(["local_nano_time", "quote_nano_time"] + HEADER_ROW) end = time() + 60 * 60 # 记录 30 min 分钟的数据分析 while True: if end < time(): break api.wait_update() for s, q in quotes.items(): if api.is_changing(q): csv_files[s][1].writerow([ f"{time()*1e9:.0f}", f"{_str_to_nano(q['datetime']):.0f}" ] + [q[k] for k in HEADER_ROW]) close_csvfiles(csv_files) api.close()
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'limin' """ 网格交易策略 参考: https://www.shinnytech.com/blog/grid-trading/ """ from functools import reduce from tqsdk import TqApi, TargetPosTask SYMBOL = "DCE.jd1901" # 合约代码 START_PRICE = 4047 # 起始价位 GRID_AMOUNT = 10 # 网格在多头、空头方向的格子(档位)数量 api = TqApi() grid_region_long = [0.005] * GRID_AMOUNT # 多头每格价格跌幅(网格密度) grid_region_short = [0.005] * GRID_AMOUNT # 空头每格价格涨幅(网格密度) grid_volume_long = [i for i in range(GRID_AMOUNT + 1)] # 多头每格交易手数 grid_volume_short = [i for i in range(GRID_AMOUNT + 1)] # 空头每格交易手数 grid_prices_long = [ reduce(lambda p, r: p * (1 - r), grid_region_long[:i], START_PRICE) for i in range(GRID_AMOUNT + 1) ] # 多头每格的触发价位列表 grid_prices_short = [ reduce(lambda p, r: p * (1 + r), grid_region_short[:i], START_PRICE) for i in range(GRID_AMOUNT + 1) ] # 空头每格的触发价位列表 print("策略开始运行, 起始价位: %f, 多头每格交易量:%s, 多头每格的价位:%s, 空头每格的价位:%s" % (START_PRICE, grid_volume_long, grid_prices_long, grid_prices_short))
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'chengzhi' from tqsdk import TqApi, TqSim ''' 如果当前价格大于10秒K线的MA15则开多仓 如果小于则平仓 ''' api = TqApi() # 获得 m1909 10秒K线的引用 klines = api.get_kline_serial("DCE.m1909", 10) # 判断开仓条件 while True: api.wait_update() if api.is_changing(klines): ma = sum(klines.close.iloc[-15:]) / 15 print("最新价", klines.close.iloc[-1], "MA", ma) if klines.close.iloc[-1] > ma: print("最新价大于MA: 市价开仓") api.insert_order(symbol="DCE.m1909", direction="BUY", offset="OPEN", volume=5) break # 判断平仓条件 while True: api.wait_update() if api.is_changing(klines): ma = sum(klines.close.iloc[-15:]) / 15
pivot = (high + low + close) / 3 # 枢轴点 bBreak = high + 2 * (pivot - low) # 突破买入价 sSetup = pivot + (high - low) # 观察卖出价 sEnter = 2 * pivot - low # 反转卖出价 bEnter = 2 * pivot - high # 反转买入价 bSetup = pivot - (high - low) # 观察买入价 sBreak = low - 2 * (high - pivot) # 突破卖出价 print("已计算新标志线: ", "\n枢轴点", pivot, "\n突破买入价", bBreak, "\n观察卖出价", sSetup, "\n反转卖出价", sEnter, "\n反转买入价", bEnter, "\n观察买入价", bSetup, "\n突破卖出价", sBreak) return pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak api = TqApi() quote = api.get_quote(SYMBOL) klines = api.get_kline_serial(SYMBOL, 24 * 60 * 60) # 86400: 使用日线 position = api.get_position(SYMBOL) target_pos = TargetPosTask(api, SYMBOL) target_pos_value = position.pos_long - position.pos_short # 目标净持仓数 open_position_price = position.open_price_long if target_pos_value > 0 else position.open_price_short # 开仓价 pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak = get_index_line( klines) # 七条标准线 while True: target_pos.set_target_volume(target_pos_value) api.wait_update() if api.is_changing(klines.iloc[-1], "datetime"): # 产生新k线,则重新计算7条指标线 pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak = get_index_line( klines)
def test_get_position(self): """ 获取持仓 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_td_basic_get_position_simulate.script.lzma")) # 测试: 获取数据 api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) order1 = api.insert_order("DCE.jd2005", "BUY", "OPEN", 1, limit_price=3345) order2 = api.insert_order("DCE.jd2005", "BUY", "OPEN", 3) order3 = api.insert_order("DCE.jd2005", "SELL", "OPEN", 3) while order1.status == "ALIVE" or order2.status == "ALIVE" or order3.status == "ALIVE": api.wait_update() position = api.get_position("DCE.jd2005") # 测试脚本重新生成后,数据根据实际情况有变化 self.assertEqual( "{'exchange_id': 'DCE', 'instrument_id': 'jd2005', 'pos_long_his': 0, 'pos_long_today': 4, 'pos_short_his': 0, 'pos_short_today': 3, 'volume_long_today': 4, 'volume_long_his': 0, 'volume_long': 4, 'volume_long_frozen_today': 0, 'volume_long_frozen_his': 0, 'volume_long_frozen': 0, 'volume_short_today': 3, 'volume_short_his': 0, 'volume_short': 3, 'volume_short_frozen_today': 0, 'volume_short_frozen_his': 0, 'volume_short_frozen': 0, 'open_price_long': 3330.0, 'open_price_short': 3324.0, 'open_cost_long': 133200.0, 'open_cost_short': 99720.0, 'position_price_long': 3330.0, 'position_price_short': 3324.0, 'position_cost_long': 133200.0, 'position_cost_short': 99720.0, 'float_profit_long': -200.0, 'float_profit_short': -30.0, 'float_profit': -230.0, 'position_profit_long': -200.0, 'position_profit_short': -30.0, 'position_profit': -230.0, 'margin_long': 11429.6, 'margin_short': 8572.2, 'margin': 20001.800000000003, 'market_value_long': 0.0, 'market_value_short': 0.0, 'market_value': 0.0, 'last_price': 3325.0}", str(position)) self.assertEqual(1, position.pos) self.assertEqual(4, position.pos_long) self.assertEqual(3, position.pos_short) self.assertEqual(position.exchange_id, "DCE") self.assertEqual(position.instrument_id, "jd2005") self.assertEqual(position.pos_long_his, 0) self.assertEqual(position.pos_long_today, 4) self.assertEqual(position.pos_short_his, 0) self.assertEqual(position.pos_short_today, 3) self.assertEqual(position.volume_long_today, 4) self.assertEqual(position.volume_long_his, 0) self.assertEqual(position.volume_long, 4) self.assertEqual(position.volume_long_frozen_today, 0) self.assertEqual(position.volume_long_frozen_his, 0) self.assertEqual(position.volume_long_frozen, 0) self.assertEqual(position.volume_short_today, 3) self.assertEqual(position.volume_short_his, 0) self.assertEqual(position.volume_short, 3) self.assertEqual(position.volume_short_frozen_today, 0) self.assertEqual(position.volume_short_frozen_his, 0) self.assertEqual(position.volume_short_frozen, 0) self.assertEqual(position.open_price_long, 3330.0) self.assertEqual(position.open_price_short, 3324.0) self.assertEqual(position.open_cost_long, 133200.0) self.assertEqual(position.open_cost_short, 99720.0) self.assertEqual(position.position_price_long, 3330.0) self.assertEqual(position.position_price_short, 3324.0) self.assertEqual(position.position_cost_long, 133200.0) self.assertEqual(position.position_cost_short, 99720.0) self.assertEqual(position.float_profit_long, -200.0) self.assertEqual(position.float_profit_short, -30.0) self.assertEqual(position.float_profit, -230.0) self.assertEqual(position.position_profit_long, -200.0) self.assertEqual(position.position_profit_short, -30.0) self.assertEqual(position.position_profit, -230.0) self.assertEqual(position.margin_long, 11429.6) self.assertEqual(position.margin_short, 8572.2) self.assertEqual(position.margin, 20001.800000000003) self.assertEqual(position.market_value_long, 0.0) self.assertEqual(position.market_value_short, 0.0) self.assertEqual(position.market_value, 0.0) self.assertEqual(position.last_price, 3325.0) # 其他取值方式测试 self.assertEqual(position["pos_long_today"], 4) self.assertEqual(position["pos_short_today"], 3) self.assertEqual(position["volume_long_his"], 0) self.assertEqual(position["volume_long"], 4) api.close()
''' 自动扶梯 策略 (难度:初级) 参考: https://www.shinnytech.com/blog/escalator/ 注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改 ''' from tqsdk import TqApi, TargetPosTask from tqsdk.ta import MA # 设置合约 SYMBOL = "SHFE.au2006" # 设置均线长短周期 MA_SLOW, MA_FAST = 8, 40 api = TqApi() klines = api.get_kline_serial(SYMBOL, 60 * 60 * 24) quote = api.get_quote(SYMBOL) position = api.get_position(SYMBOL) target_pos = TargetPosTask(api, SYMBOL) # K线收盘价在这根K线波动范围函数 def kline_range(num): kl_range = (klines.iloc[num].close - klines.iloc[num].low) / \ (klines.iloc[num].high - klines.iloc[num].low) return kl_range
def test_insert_order(self): """ 下单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_td_basic_insert_order_simulate.script.lzma")) # 测试: 模拟账户下单 # 非回测, 则需在盘中生成测试脚本: 测试脚本重新生成后,数据根据实际情况有变化,因此需要修改assert语句的内容 TqApi.RD = random.Random(2) api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) order1 = api.insert_order("DCE.jd2005", "BUY", "OPEN", 1) order2 = api.insert_order("SHFE.cu2004", "BUY", "OPEN", 2, limit_price=49200) while order1.status == "ALIVE" or order2.status == "ALIVE": api.wait_update() self.assertEqual(order1.order_id, "5c6e433715ba2bdd177219d30e7a269f") self.assertEqual(order1.direction, "BUY") self.assertEqual(order1.offset, "OPEN") self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertNotEqual(order1.limit_price, order1.limit_price) # 判断nan self.assertEqual(order1.price_type, "ANY") self.assertEqual(order1.volume_condition, "ANY") self.assertEqual(order1.time_condition, "IOC") self.assertAlmostEqual(1584423143664478000 / 1e9, order1.insert_date_time / 1e9, places=1) self.assertEqual(order1.status, "FINISHED") for k, v in order1.trade_records.items(): # 模拟交易为一次性全部成交,因此只有一条成交记录 self.assertAlmostEqual(1584423143664478000 / 1e9, v.trade_date_time / 1e9, places=1) del v.trade_date_time self.assertEqual( str(v), "{'order_id': '5c6e433715ba2bdd177219d30e7a269f', 'trade_id': '5c6e433715ba2bdd177219d30e7a269f|1', 'exchange_trade_id': '5c6e433715ba2bdd177219d30e7a269f|1', 'exchange_id': 'DCE', 'instrument_id': 'jd2005', 'direction': 'BUY', 'offset': 'OPEN', 'price': 3205.0, 'volume': 1, 'user_id': 'TQSIM', 'commission': 6.122999999999999}" ) self.assertEqual(order2.order_id, "cf1822ffbc6887782b491044d5e34124") self.assertEqual(order2.direction, "BUY") self.assertEqual(order2.offset, "OPEN") self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order2.limit_price, 49200.0) self.assertEqual(order2.price_type, "LIMIT") self.assertEqual(order2.volume_condition, "ANY") self.assertEqual(order2.time_condition, "GFD") self.assertAlmostEqual(1584423143666130000 / 1e9, order2.insert_date_time / 1e9, places=1) self.assertEqual(order2.status, "FINISHED") for k, v in order2.trade_records.items(): # 模拟交易为一次性全部成交,因此只有一条成交记录 self.assertAlmostEqual(1584423143666130000 / 1e9, v.trade_date_time / 1e9, places=1) del v.trade_date_time self.assertEqual( str(v), "{'order_id': 'cf1822ffbc6887782b491044d5e34124', 'trade_id': 'cf1822ffbc6887782b491044d5e34124|2', 'exchange_trade_id': 'cf1822ffbc6887782b491044d5e34124|2', 'exchange_id': 'SHFE', 'instrument_id': 'cu2004', 'direction': 'BUY', 'offset': 'OPEN', 'price': 49200.0, 'volume': 2, 'user_id': 'TQSIM', 'commission': 23.189999999999998}" ) api.close()
wma_data = ema2(close_prices, 30)[-n:] # WMA指标 mom_data = trma(close_prices, 30)[-n:] # MOM指标 x_all = list(zip(sma_data, wma_data, mom_data)) # 样本特征组 y_all = list(klines.close.iloc[i] >= klines.close.iloc[i - 1] for i in list(reversed(range(-1, -n - 1, -1)))) # 样本标签组 # x_all: 大前天指标 前天指标 昨天指标 (今天指标) # y_all: (大前天) 前天 昨天 今天 -明天- # 准备算法需要用到的数据 x_train = x_all[: -1] # 训练数据: 特征 x_predict = x_all[-1] # 预测数据(用本交易日的指标预测下一交易日的涨跌) y_train = y_all[1:] # 训练数据: 标签 (去掉第一个数据后让其与指标隔一位对齐(例如: 昨天的特征 -> 对应预测今天的涨跌标签)) return x_train, y_train, x_predict predictions = [] # 用于记录每次的预测结果(在每个交易日收盘时用收盘数据预测下一交易日的涨跌,并记录在此列表里) api = TqApi(TqSim(), backtest=TqBacktest(start_dt=datetime.date(2018, 7, 2), end_dt=datetime.date(2018, 9, 26))) quote = api.get_quote(symbol) klines = api.get_kline_serial(symbol, duration_seconds=24 * 60 * 60) # 日线 target_pos = TargetPosTask(api, symbol) with closing(api): try: while True: while not api.is_changing(klines.iloc[-1], "datetime"): # 等到达下一个交易日 api.wait_update() while True: api.wait_update() # 在收盘后预测下一交易日的涨跌情况 if api.is_changing(quote, "datetime"): now = datetime.datetime.strptime(quote.datetime, "%Y-%m-%d %H:%M:%S.%f") # 当前quote的时间 # 判断是否到达预定收盘时间: 如果到达 则认为本交易日收盘, 此时预测下一交易日的涨跌情况, 并调整为对应仓位 if now.hour == close_hour and now.minute >= close_minute:
def test_cancel_order_option(self): """ 撤单 注:本函数不是回测,重新盘中生成测试用例script文件时更改为当前可交易的合约代码,且_ins_url可能需修改。 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join( dir_path, "log_file", "test_td_basic_cancel_order_simulate_option.script.lzma")) # 测试: 模拟账户 TqApi.RD = random.Random(2) api = TqApi(_ins_url=self.ins_url_2020_04_02, _td_url=self.td_url, _md_url=self.md_url) order1 = api.insert_order("DCE.m2007-P-2900", "BUY", "OPEN", 1, limit_price=150) order2 = api.insert_order("SHFE.cu2006C47000", "BUY", "OPEN", 2, limit_price=135) api.wait_update() self.assertEqual("ALIVE", order1.status) self.assertEqual("ALIVE", order2.status) api.cancel_order(order1) api.cancel_order(order2.order_id) while order1.status != "FINISHED" or order2.status != "FINISHED": api.wait_update() self.assertEqual("FINISHED", order1.status) self.assertEqual("FINISHED", order2.status) self.assertNotEqual(order1.volume_left, 0) self.assertNotEqual(order2.volume_left, 0) api.close()
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'chengzhi' from tqsdk import TqApi, TqSim api = TqApi(TqSim()) # 获得 m1909 的持仓引用,当持仓有变化时 position 中的字段会对应更新 position = api.get_position("DCE.m1909") # 获得资金账户引用,当账户有变化时 account 中的字段会对应更新 account = api.get_account() # 下单并返回委托单的引用,当该委托单有变化时 order 中的字段会对应更新 order = api.insert_order(symbol="DCE.m1909", direction="BUY", offset="OPEN", volume=5) while True: api.wait_update() if api.is_changing(order, ["status", "volume_orign", "volume_left"]): print("单状态: %s, 已成交: %d 手" % (order.status, order.volume_orign - order.volume_left)) if api.is_changing(position, "volume_long_today"): print("今多头: %d 手" % (position.volume_long_today)) if api.is_changing(account, "available"): print("可用资金: %.2f" % (account.available))
def init_api(self): self.api = TqApi() while True: sleep(60)
symbol = "DCE.jd2001" # 合约代码 start_price = 4247 # 起始价位 grid_amount = 10 # 网格在多头、空头方向的格子(档位)数量 grid_region_long = [0.005] * grid_amount # 多头每格价格跌幅(网格密度) grid_region_short = [0.005] * grid_amount # 空头每格价格涨幅(网格密度) grid_volume_long = [1] * grid_amount # 多头每格交易手数 grid_volume_short = [-1] * grid_amount # 空头每格交易手数 grid_prices_long = [reduce(lambda p, r: p*(1-r), grid_region_long[:i], start_price) for i in range(grid_amount + 1)] # 多头每格的触发价位列表, 第一个元素为起始价位 grid_prices_short = [reduce(lambda p, r: p*(1+r), grid_region_short[:i], start_price) for i in range(grid_amount + 1)] # 空头每格的触发价位列表, 第一个元素为起始价位 print("起始价位:", start_price) print("多头每格交易量:", grid_volume_long) print("多头每格的价位:", grid_prices_long) print("空头每格的价位:", grid_prices_short) api = TqApi() quote = api.get_quote(symbol) # 行情数据 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)
def test_is_changing(self): """is_changing() 测试""" # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_func_basic_is_changing.script.lzma")) # 测试: 模拟账户下单 TqApi.RD = random.Random(4) api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) quote = api.get_quote("SHFE.rb2001") position = api.get_position("SHFE.rb2001") order1 = api.insert_order("DCE.m2001", "BUY", "OPEN", 1) api.wait_update() order2 = api.insert_order("SHFE.rb2001", "SELL", "OPEN", 2) api.wait_update() self.assertTrue(api.is_changing(order2, "status")) self.assertTrue(api.is_changing(position, "volume_short")) self.assertFalse(api.is_changing(position, "volume_long")) order3 = api.insert_order("SHFE.rb2001", "BUY", "CLOSETODAY", 1) while order3.status == "ALIVE": api.wait_update() self.assertTrue(api.is_changing(order3, "status")) self.assertTrue(api.is_changing(position, "volume_short")) self.assertFalse(api.is_changing(quote, "last_price")) api.close()
from tqsdk import TqApi from DataLoader import download_data, read_data from datetime import datetime api = TqApi() quotes = api._data['quotes'] symbols = [] for symbol, item in quotes.items(): if item['ins_class'] == 'FUTURE': symbols.append(symbol) download_data(symbols[0:500], datetime(2016, 1, 1), datetime(2020, 8, 31), "tick") #download_data(symbols, datetime(2016,1,1), datetime(2020,8,25), "D")
def init_api(self): self.api = TqApi() while True: self.api.wait_update()
def test_lib_insert_order_time_check_4(self): ''' lib下单时间判断测试4 回测时间: 起始交易日(datetime.date)为周一 订阅合约: cu(有夜盘,凌晨1点结束夜盘),rb(夜盘23点结束),jd(无夜盘) 测试: (测试周五夜盘21点到周六凌晨1点及周一夜盘、周二白盘) 1 周五晚21:00之后: cu、rb能下单, jd到周一的9点后下单 2 周六凌晨1点前:cu能下单 3 周一早9点后都能下单 4 周一晚21点后cu、rb能下单 5 周二白盘开始后,jd能下单 ''' # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_lib_insert_order_time_check_4.script.lzma")) TqApi.RD = random.Random(4) api = TqApi(backtest=TqBacktest(datetime.date(2019, 12, 2), datetime.date(2019, 12, 3)), _ins_url=self.ins_url_2019_12_04) # 2019.12.2:周一 symbol1 = "SHFE.cu2002" # 有夜盘,凌晨1点结束夜盘 symbol2 = "SHFE.rb2002" # 夜盘23点结束 symbol3 = "DCE.jd2002" # 无夜盘 quote1 = api.get_quote(symbol1) quote2 = api.get_quote(symbol2) quote3 = api.get_quote(symbol3) position1 = api.get_position(symbol1) position2 = api.get_position(symbol2) position3 = api.get_position(symbol3) target_pos1 = TargetPosTask(api, symbol1) target_pos2 = TargetPosTask(api, symbol2) target_pos3 = TargetPosTask(api, symbol3) orders = api.get_order() try: # 1 周五晚21:00之后: cu、rb能下单, jd到周一的9点后下单 target_pos1.set_target_volume(1) target_pos2.set_target_volume(2) target_pos3.set_target_volume(3) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-11-29 21:05:00.000000": api.wait_update() self.assertEqual(len(orders), 2) self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 0) # 2 周五23点后到周六凌晨1点前:cu能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-11-29 23:00:00.000000": api.wait_update() target_pos1.set_target_volume(4) target_pos2.set_target_volume(5) target_pos3.set_target_volume(6) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-11-29 23:05:00.000000": api.wait_update() self.assertEqual(len(orders), 3) self.assertEqual(position1.pos, 4) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 0) # 3 周一早9点后都能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-02 09:05:00.000000": api.wait_update() self.assertEqual(len(orders), 5) self.assertEqual(position1.pos, 4) self.assertEqual(position2.pos, 5) self.assertEqual(position3.pos, 6) # 4 周一晚21点后cu、rb能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-02 21:00:00.000000": api.wait_update() target_pos1.set_target_volume(0) target_pos2.set_target_volume(0) target_pos3.set_target_volume(0) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-02 21:15:00.000000": api.wait_update() self.assertEqual(len(orders), 7) self.assertEqual(position1.pos, 0) self.assertEqual(position2.pos, 0) self.assertEqual(position3.pos, 6) # 5 周二白盘开始后,jd能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-03 09:02:00.000000": api.wait_update() self.assertEqual(len(orders), 8) while True: api.wait_update() except BacktestFinished: self.assertEqual(len(orders), 8) self.assertEqual(position1.pos, 0) self.assertEqual(position2.pos, 0) self.assertEqual(position3.pos, 0) api.close()