def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url_2019_07_03 = "http://127.0.0.1:5000/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/"
def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url = "http://127.0.0.1:5000/" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/"
def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url_2020_04_02 = "http://127.0.0.1:5000/t/md/symbols/2020-04-02.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/"
class TestMdBasic(unittest.TestCase): """ 行情部分基本功能测试. 测试TqApi行情相关函数, 以及TqApi与行情服务器交互是否符合设计预期 """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url = "http://127.0.0.1:5000/" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.mock.close() self.ins.close() def test_get_quote_normal(self): """ 获取行情报价 """ # 预设服务器端响应 self.mock.run("test_md_basic_get_quote_normal.script") # 获取行情 api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) q = api.get_quote("SHFE.cu1901") self.assertEqual(46940.0, q.last_price) api.close()
def setUp(self): # self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/"
def setUp(self): # self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url_2019_12_04 = "https://openmd.shinnytech.com/t/md/symbols/2019-12-04.json" self.ins_url_2020_02_18 = "https://openmd.shinnytech.com/t/md/symbols/2020-02-18.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/"
class TestFuncBasic(unittest.TestCase): """ TqApi中功能函数的基本功能测试. 注: 1. 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2. 若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 TqApi.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 3. 对盘中的测试用例(即非回测):因为TqSim模拟交易 Order 的 insert_date_time 和 Trade 的 trade_date_time 不是固定值,所以改为判断范围。 盘中时:self.assertAlmostEqual(1575292560005832000 / 1e9, order1.insert_date_time / 1e9, places=1) 回测时:self.assertEqual(1575291600000000000, order1.insert_date_time) """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url_2020_04_02 = "http://127.0.0.1:5000/t/md/symbols/2020-04-02.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() def test_is_changing(self): """ is_changing() 测试 注:本函数不是回测,重新生成测试用例script文件时更改为当前可交易的合约代码,在盘中生成,且_ins_url可能需修改。 """ # 预设服务器端响应 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")) # 测试: 模拟账户下单 utils.RD = random.Random(4) api = TqApi(_ins_url=self.ins_url_2020_04_02, _td_url=self.td_url, _md_url=self.md_url) quote = api.get_quote("SHFE.rb2010") position = api.get_position("SHFE.rb2010") order1 = api.insert_order("DCE.m2009", "BUY", "OPEN", 1) api.wait_update() order2 = api.insert_order("SHFE.rb2010", "SELL", "OPEN", 2, 3100.0) 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.rb2010", "BUY", "CLOSETODAY", 1, 3290.0) 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()
class TestMdBacktest(unittest.TestCase): ''' 行情回测测试 ''' def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url_2019_07_03 = "http://127.0.0.1:5000/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() def test_get_quote_backtest(self): """ 回测获取行情报价 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_md_backtest_get_quote.script.lzma")) # 测试 try: utils.RD = random.Random(1) api = TqApi(backtest=TqBacktest(datetime(2019, 10, 15), datetime(2019, 10, 16)), _ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) with closing(api): quote = api.get_quote("SHFE.cu2001") quote_data = {k: v for k, v in quote.items()} quote_data["trading_time"] = { k: v for k, v in quote_data["trading_time"].items() } self.assertEqual( json.dumps(quote_data, sort_keys=True), '{"amount": NaN, "ask_price1": 47070.0, "ask_price2": NaN, "ask_price3": NaN, "ask_price4": NaN, "ask_price5": NaN, "ask_volume1": 1, "ask_volume2": 0, "ask_volume3": 0, "ask_volume4": 0, "ask_volume5": 0, "average": NaN, "bid_price1": 47050.0, "bid_price2": NaN, "bid_price3": NaN, "bid_price4": NaN, "bid_price5": NaN, "bid_volume1": 1, "bid_volume2": 0, "bid_volume3": 0, "bid_volume4": 0, "bid_volume5": 0, "close": NaN, "commission": 11.594999999999999, "datetime": "2019-10-14 23:59:59.999999", "delivery_month": 1, "delivery_year": 2020, "expire_datetime": 1579071600.0, "expired": false, "highest": NaN, "ins_class": "FUTURE", "instrument_id": "SHFE.cu2001", "last_price": 47060.0, "lower_limit": NaN, "lowest": NaN, "margin": 16233.000000000002, "max_limit_order_volume": 500, "max_market_order_volume": 0, "min_limit_order_volume": 0, "min_market_order_volume": 0, "open": NaN, "open_interest": 45357, "option_class": "", "pre_close": NaN, "pre_open_interest": 0, "pre_settlement": NaN, "price_decs": 0, "price_tick": 10, "product_id": "cu", "settlement": NaN, "strike_price": NaN, "trading_time": {"day": [["09:00:00", "10:15:00"], ["10:30:00", "11:30:00"], ["13:30:00", "15:00:00"]], "night": [["21:00:00", "25:00:00"]]}, "underlying_symbol": "", "upper_limit": NaN, "volume": 0, "volume_multiple": 5}' ) # 其他取值方式 self.assertNotEqual(quote["pre_close"], quote.pre_close) self.assertNotEqual(quote.get("pre_settlement"), quote.pre_settlement) self.assertNotEqual(quote.get("highest"), quote.highest) self.assertNotEqual(quote.get("lowest"), quote.lowest) self.assertNotEqual(quote["open"], quote.open) self.assertNotEqual(quote["close"], quote.close) except BacktestFinished: api.close() print("backtest finished")
class TestFuncBasic(unittest.TestCase): """ TqApi中功能函数的基本功能测试. 注: 1: 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2:若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 TqApi.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() 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")) # 测试: 模拟账户下单 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.assertEqual(api.is_changing(order2, "status"), True) self.assertEqual(api.is_changing(position, "volume_short"), True) self.assertEqual(api.is_changing(position, "volume_long"), False) order3 = api.insert_order("SHFE.rb2001", "BUY", "CLOSETODAY", 1) while order3.status == "ALIVE": api.wait_update() self.assertEqual(api.is_changing(order3, "status"), True) self.assertEqual(api.is_changing(position, "volume_short"), True) self.assertEqual(api.is_changing(quote, "last_price"), False) api.close()
class TestWaitUpdateFunction(unittest.TestCase): """ 功能函数 wait_update() 测试. 注: 1. 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2. 若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 utils.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 3. 對盤中的測試用例(即非回測):因为TqSim模拟交易 Order 的 insert_date_time 和 Trade 的 trade_date_time 不是固定值,所以改为判断范围。 盘中时:self.assertAlmostEqual(1575292560005832000 / 1e9, order1.insert_date_time / 1e9, places=1) 回测时:self.assertEqual(1575291600000000000, order1.insert_date_time) """ def setUp(self): # self.ins = MockInsServer(5000) self.mock = MockServer() self.ins_url_2019_07_03 = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): # self.ins.close() self.mock.close() def test_wait_update_1(self): """ 若未连接天勤时修改了K线字段,则不应发送set_chart_data指令到服务器 (即不能调用api.py中_process_serial_extra_array()); 否则导致与服务器断连 related issue: #146 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_func_wait_update_1.script.lzma")) # 测试 api = TqApi(_ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) utils.RD = random.Random(4) klines = api.get_kline_serial("SHFE.cu1911", 10) klines["ma"] = MA(klines, 15) # 测试语句 deadline = time.time() + 10 while api.wait_update(deadline=deadline): pass api.close()
class TestFuncBasic(unittest.TestCase): """ 功能函数部分基本功能测试. 测试TqApi功能相关函数 """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() # @unittest.skip("无条件跳过") def test_is_changing(self): # 预设服务器端响应 self.mock.run("test_func_basic_is_changing.script") # 测试: 模拟账户下单 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.assertEqual(api.is_changing(order2, "status"), True) self.assertEqual(api.is_changing(position, "volume_short"), True) self.assertEqual(api.is_changing(position, "volume_long"), False) order3 = api.insert_order("SHFE.rb2001", "BUY", "CLOSETODAY", 1) while order3.status == "ALIVE": api.wait_update() self.assertEqual(api.is_changing(order3, "status"), True) self.assertEqual(api.is_changing(position, "volume_short"), True) self.assertEqual(api.is_changing(quote, "last_price"), False)
class TestWaitUpdateFunction(unittest.TestCase): """ 功能函数 wait_update() 测试. 注: 1: 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2:若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 TqApi.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() self.ins_url = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() # @unittest.skip("无条件跳过") def test_wait_update_1(self): """ 若未连接天勤时修改了K线字段,则不应发送set_chart_data指令到服务器 (即不能调用api.py中_process_serial_extra_array()); 否则导致与服务器断连 related issue: #146 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "test_func_wait_update_1.script")) #测试 api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) TqApi.RD = random.Random(4) klines = api.get_kline_serial("SHFE.cu1911", 10) klines["ma"] = MA(klines, 15) # 测试语句 deadline = time.time() + 10 while api.wait_update(deadline=deadline): pass api.close()
def backtest(): """ 回测耗时测试 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) log_path = os.path.join(dir_path, "log_file", "test_backtest.script.lzma") times = [] for i in range(20): mock = MockServer() md_url = "ws://127.0.0.1:5100/" td_url = "ws://127.0.0.1:5200/" mock.run(log_path) utils.RD = random.Random(4) try: start = datetime.datetime.now() backtest = TqBacktest( start_dt=datetime.datetime(2019, 8, 10), end_dt=datetime.datetime(2019, 9, 11)) api = TqApi(backtest=backtest, _ins_url=self.ins_url_2019_07_03, _md_url=md_url, _td_url=td_url) symbol = "DCE.m2005" klines = api.get_kline_serial(symbol, duration_seconds=60) while True: api.wait_update() except BacktestFinished: delta = datetime.datetime.now() - start self.assertLess(delta.seconds, 60) times.append(delta.seconds + delta.microseconds * 1e-6) # print(delta.seconds + delta.microseconds * 1e-6) api.close() mock.close() print(times) print(sum(times))
class TestTdBasic(unittest.TestCase): """ 测试TqApi交易相关函数基本功能, 以及TqApi与交易服务器交互是否符合设计预期 注: 1. 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2. 若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 TqApi.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 3. 對盤中的測試用例(即非回測):因为TqSim模拟交易 Order 的 insert_date_time 和 Trade 的 trade_date_time 不是固定值,所以改为判断范围。 盘中时:self.assertAlmostEqual(1575292560005832000 / 1e9, order1.insert_date_time / 1e9, places=1) 回测时:self.assertEqual(1575291600000000000, order1.insert_date_time) """ def setUp(self): # self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): # self.ins.close() self.mock.close() # 模拟交易测试 # @unittest.skip("无条件跳过") 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, 'symbol': 'DCE.jd2005', '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, 'symbol': 'SHFE.cu2004', 'user_id': 'TQSIM', 'commission': 23.189999999999998}" ) api.close() def test_cancel_order(self): """ 撤单 """ # 预设服务器端响应 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.script.lzma")) # 测试: 模拟账户 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.jd2001", "BUY", "OPEN", 1, limit_price=4570) order2 = api.insert_order("SHFE.cu2001", "BUY", "OPEN", 2, limit_price=47070) api.wait_update() self.assertEqual("ALIVE", order1.status) self.assertEqual("ALIVE", order2.status) api.cancel_order(order1) api.cancel_order(order2.order_id) api.wait_update() self.assertEqual("FINISHED", order1.status) self.assertEqual("FINISHED", order2.status) api.close() def test_get_account(self): """ 获取账户资金信息 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_td_basic_get_account_simulate.script.lzma")) # 测试: 获取数据 api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) TqApi.RD = random.Random(4) order = api.insert_order("DCE.jd2001", "BUY", "OPEN", 1, limit_price=4570) while order.status == "ALIVE": api.wait_update() account = api.get_account() # 测试脚本重新生成后,数据根据实际情况有变化 self.assertEqual( str(account), "{'currency': 'CNY', 'pre_balance': 10000000.0, 'static_balance': 10000000.0, 'balance': 9994873.877, 'available': 9992016.477, 'float_profit': -5120.0, 'position_profit': -5120.0, 'close_profit': 0.0, 'frozen_margin': 0.0, 'margin': 2857.4, 'frozen_commission': 0.0, 'commission': 6.122999999999999, 'frozen_premium': 0.0, 'premium': 0.0, 'deposit': 0.0, 'withdraw': 0.0, 'risk_ratio': 0.00028588654896140217}" ) self.assertEqual(account.currency, "CNY") self.assertEqual(account.pre_balance, 10000000.0) self.assertEqual(9994873.877, account.balance) self.assertEqual(6.122999999999999, account["commission"]) self.assertEqual(2857.4, account["margin"]) self.assertEqual(-5120.0, account.position_profit) api.close() 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.jd2001", "BUY", "OPEN", 1, limit_price=4592) order2 = api.insert_order("DCE.jd2001", "BUY", "OPEN", 3) order3 = api.insert_order("DCE.jd2001", "SELL", "OPEN", 3) while order1.status == "ALIVE" or order2.status == "ALIVE" or order3.status == "ALIVE": api.wait_update() position = api.get_position("DCE.jd2001") # 测试脚本重新生成后,数据根据实际情况有变化 self.assertEqual( "{'exchange_id': 'DCE', 'instrument_id': 'jd2001', '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': 4193.0, 'open_price_short': 4059.0, 'open_cost_long': 167720.0, 'open_cost_short': 121770.0, 'position_price_long': 4193.0, 'position_price_short': 4059.0, 'position_cost_long': 167720.0, 'position_cost_short': 121770.0, 'float_profit_long': -5320.0, 'float_profit_short': -30.0, 'float_profit': -5350.0, 'position_profit_long': -5320.0, 'position_profit_short': -30.0, 'position_profit': -5350.0, 'margin_long': 11429.6, 'margin_short': 8572.2, 'margin': 20001.800000000003, 'symbol': 'DCE.jd2001', 'last_price': 4060.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, "jd2001") 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, 4193.0) self.assertEqual(position.open_price_short, 4059.0) self.assertEqual(position.open_cost_long, 167720.0) self.assertEqual(position.open_cost_short, 121770.0) self.assertEqual(position.position_price_long, 4193.0) self.assertEqual(position.position_price_short, 4059.0) self.assertEqual(position.position_cost_long, 167720.0) self.assertEqual(position.position_cost_short, 121770.0) self.assertEqual(position.float_profit_long, -5320.0) self.assertEqual(position.float_profit_short, -30.0) self.assertEqual(position.float_profit, -5350.0) self.assertEqual(position.position_profit_long, -5320.0) self.assertEqual(position.position_profit_short, -30.0) self.assertEqual(position.position_profit, -5350.0) self.assertEqual(position.margin_long, 11429.6) self.assertEqual(position.margin_short, 8572.2) self.assertEqual(position.margin, 20001.800000000003) self.assertEqual(position.symbol, "DCE.jd2001") self.assertEqual(position.last_price, 4060.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() def test_get_trade(self): """ 获取成交记录 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_td_basic_get_trade_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.jd2001", "BUY", "OPEN", 1) order2 = api.insert_order("SHFE.cu2001", "BUY", "OPEN", 2, limit_price=49200) while order1.status == "ALIVE" or order2.status == "ALIVE": api.wait_update() trade1 = api.get_trade("1710cf5327ac435a7a97c643656412a9|1") trade2 = api.get_trade("8ca5996666ceab360512bd1311072231|2") self.assertAlmostEqual(1576114914812000000 / 1e9, trade1.trade_date_time / 1e9, places=1) self.assertAlmostEqual(1576114916000000000 / 1e9, trade2.trade_date_time / 1e9, places=1) del trade1["trade_date_time"] del trade2["trade_date_time"] self.assertEqual( str(trade1), "{'order_id': '1710cf5327ac435a7a97c643656412a9', 'trade_id': '1710cf5327ac435a7a97c643656412a9|1', 'exchange_trade_id': '1710cf5327ac435a7a97c643656412a9|1', 'exchange_id': 'DCE', 'instrument_id': 'jd2001', 'direction': 'BUY', 'offset': 'OPEN', 'price': 4058.0, 'volume': 1, 'symbol': 'DCE.jd2001', 'user_id': 'TQSIM', 'commission': 6.122999999999999}" ) self.assertEqual( str(trade2), "{'order_id': '8ca5996666ceab360512bd1311072231', 'trade_id': '8ca5996666ceab360512bd1311072231|2', 'exchange_trade_id': '8ca5996666ceab360512bd1311072231|2', 'exchange_id': 'SHFE', 'instrument_id': 'cu2001', 'direction': 'BUY', 'offset': 'OPEN', 'price': 49200.0, 'volume': 2, 'symbol': 'SHFE.cu2001', 'user_id': 'TQSIM', 'commission': 23.189999999999998}" ) self.assertEqual(trade1.direction, "BUY") self.assertEqual(trade1.offset, "OPEN") self.assertEqual(trade1.price, 4058.0) self.assertEqual(trade1.volume, 1) self.assertEqual(trade1.commission, 6.122999999999999) self.assertEqual(trade2.direction, "BUY") self.assertEqual(trade2.offset, "OPEN") self.assertEqual(trade2.price, 49200.0) self.assertEqual(trade2.volume, 2) self.assertEqual(trade2.commission, 23.189999999999998) api.close() 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.jd2001", "BUY", "OPEN", 1) order2 = api.insert_order("SHFE.cu2001", "SELL", "OPEN", 2, limit_price=47040) 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(1576121399900001000 / 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.symbol, "DCE.jd2001") 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, 47040) self.assertEqual(get_order2.price_type, "LIMIT") self.assertEqual(get_order2.volume_condition, "ANY") self.assertEqual(get_order2.time_condition, "GFD") self.assertAlmostEqual(1576121399900001000 / 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.symbol, "SHFE.cu2001") 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': 'jd2001', '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', 'symbol': 'DCE.jd2001', 'frozen_margin': 0.0}" ) self.assertEqual( str(get_order2), "{'order_id': '8ca5996666ceab360512bd1311072231', 'exchange_order_id': '8ca5996666ceab360512bd1311072231', 'exchange_id': 'SHFE', 'instrument_id': 'cu2001', 'direction': 'SELL', 'offset': 'OPEN', 'volume_orign': 2, 'volume_left': 0, 'limit_price': 47040.0, 'price_type': 'LIMIT', 'volume_condition': 'ANY', 'time_condition': 'GFD', 'last_msg': '全部成交', 'status': 'FINISHED', 'user_id': 'TQSIM', 'symbol': 'SHFE.cu2001', 'frozen_margin': 0.0}" ) api.close()
class TestTdBacktest(unittest.TestCase): """ 回测时的交易测试. 注: 1: 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2:若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 TqApi.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 """ def setUp(self): # self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): # self.ins.close() self.mock.close() def test_various_combinations_of_order_1(self): """ 测试 能在回测时正常使用开、平顺序的多种组合方式下单 1 单次开平 * n次 (本测试函数) 2 多次开 一次全平完 3 多次开 分多次平完 4 单次开 分多次平完 related commit: a2623aed0fd1d5e5e01c7d2452e7f7f7de999c6e """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_various_combinations_of_order_1.script")) # 测试1:单次开平 * n次 TqApi.RD = random.Random(4) api = TqApi(backtest=TqBacktest(start_dt=datetime(2019, 12, 10, 9), end_dt=datetime(2019, 12, 11))) symbol = "DCE.m2005" position = api.get_position(symbol) for i in range(3): order_open = api.insert_order(symbol, "BUY", "OPEN", 1) while order_open.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 1) order_close = api.insert_order(symbol, "SELL", "CLOSE", 1) while order_close.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 0) api.close() def test_various_combinations_of_order_2(self): """ 测试 能在回测时正常使用开、平顺序的多种组合方式下单 1 单次开平 * n次 2 多次开 一次全平完 (本测试函数) 3 多次开 分多次平完 4 单次开 分多次平完 related commit: a2623aed0fd1d5e5e01c7d2452e7f7f7de999c6e """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_various_combinations_of_order_2.script")) # 测试2:多次开,一次全平完 TqApi.RD = random.Random(4) api = TqApi(backtest=TqBacktest(start_dt=datetime(2019, 12, 10, 9), end_dt=datetime(2019, 12, 11))) symbol = "DCE.m2005" position = api.get_position(symbol) order_open1 = api.insert_order(symbol, "BUY", "OPEN", 1) order_open2 = api.insert_order(symbol, "BUY", "OPEN", 1) order_open3 = api.insert_order(symbol, "BUY", "OPEN", 1) while order_open1.status != "FINISHED" or order_open2.status != "FINISHED" or order_open3.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 3) order_close1 = api.insert_order(symbol, "SELL", "CLOSE", 3) while order_close1.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 0) api.close() def test_various_combinations_of_order_3(self): """ 测试 能在回测时正常使用开、平顺序的多种组合方式下单 1 单次开平 * n次 2 多次开 一次全平完 3 多次开 分多次平完 (本测试函数) 4 单次开 分多次平完 related commit: a2623aed0fd1d5e5e01c7d2452e7f7f7de999c6e """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_various_combinations_of_order_3.script")) # 测试3:多次开 分多次平完 TqApi.RD = random.Random(4) api = TqApi(backtest=TqBacktest(start_dt=datetime(2019, 12, 10, 9), end_dt=datetime(2019, 12, 11))) symbol = "DCE.m2005" position = api.get_position(symbol) t = 3 for i in range(t): order_open = api.insert_order(symbol, "BUY", "OPEN", 1) while order_open.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, i + 1) for i in range(t): order_close = api.insert_order(symbol, "SELL", "CLOSE", 1) while order_close.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, t - 1 - i) api.close() def test_various_combinations_of_order_4(self): """ 测试 能在回测时正常使用开、平顺序的多种组合方式下单 1 单次开平 * n次 2 多次开 一次全平完 3 多次开 分多次平完 4 单次开 分多次平完 (本测试函数) related commit: a2623aed0fd1d5e5e01c7d2452e7f7f7de999c6e """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_various_combinations_of_order_4.script")) # 测试4:单次开 分多次平完 TqApi.RD = random.Random(4) api = TqApi(backtest=TqBacktest(start_dt=datetime(2019, 12, 10, 9), end_dt=datetime(2019, 12, 11))) symbol = "DCE.m2005" position = api.get_position(symbol) trades = api.get_trade() order_open = api.insert_order(symbol, "BUY", "OPEN", 3) while order_open.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 3) for i in range(3): order_close = api.insert_order(symbol, "SELL", "CLOSE", 1) while order_close.status != "FINISHED": api.wait_update() self.assertEqual(len(trades), 4) self.assertEqual(position.pos, 0) api.close()
class TestTdBasic(unittest.TestCase): """ 测试TqApi交易相关函数基本功能, 以及TqApi与交易服务器交互是否符合设计预期 注: 1. 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2. 若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 utils.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 3. 對盤中的測試用例(即非回測):因为TqSim模拟交易 Order 的 insert_date_time 和 Trade 的 trade_date_time 不是固定值,所以改为判断范围。 盘中时:self.assertAlmostEqual(1575292560005832000 / 1e9, order1.insert_date_time / 1e9, places=1) 回测时:self.assertEqual(1575291600000000000, order1.insert_date_time) """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url_2019_07_03 = "http://127.0.0.1:5000/t/md/symbols/2019-07-03.json" self.ins_url_2020_04_02 = "http://127.0.0.1:5000/t/md/symbols/2020-04-02.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() # 模拟交易测试 # @unittest.skip("无条件跳过") 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语句的内容 utils.RD = random.Random(2) api = TqApi(_ins_url=self.ins_url_2019_07_03, _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() def test_cancel_order(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.script.lzma")) # 测试: 模拟账户 utils.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.jd2005", "BUY", "OPEN", 1, limit_price=3040) order2 = api.insert_order("SHFE.cu2005", "BUY", "OPEN", 2, limit_price=39600) 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() def test_get_account(self): """ 获取账户资金信息 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_td_basic_get_account_simulate.script.lzma")) # 测试: 获取数据 api = TqApi(_ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) utils.RD = random.Random(4) order = api.insert_order("DCE.jd2005", "BUY", "OPEN", 1, limit_price=3340) while order.status == "ALIVE": api.wait_update() account = api.get_account() # 测试脚本重新生成后,数据根据实际情况有变化 self.assertEqual( str(account), "{'currency': 'CNY', 'pre_balance': 10000000.0, 'static_balance': 10000000.0, 'balance': 9999873.877, 'available': 9997016.477, 'ctp_balance': nan, 'ctp_available': nan, 'float_profit': -120.0, 'position_profit': -120.0, 'close_profit': 0.0, 'frozen_margin': 0.0, 'margin': 2857.4, 'frozen_commission': 0.0, 'commission': 6.122999999999999, 'frozen_premium': 0.0, 'premium': 0.0, 'deposit': 0.0, 'withdraw': 0.0, 'risk_ratio': 0.00028574360388405526, 'market_value': 0.0}" ) self.assertEqual(account.currency, "CNY") self.assertEqual(account.pre_balance, 10000000.0) self.assertEqual(9999873.877, account.balance) self.assertEqual(6.122999999999999, account["commission"]) self.assertEqual(2857.4, account["margin"]) self.assertEqual(-120.0, account.position_profit) api.close() 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_2019_07_03, _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() def test_get_trade(self): """ 获取成交记录 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_td_basic_get_trade_simulate.script.lzma")) # 测试: 模拟账户 utils.RD = random.Random(4) api = TqApi(_ins_url=self.ins_url_2019_07_03, _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", "BUY", "OPEN", 2, limit_price=40870) while order1.status == "ALIVE" or order2.status == "ALIVE": api.wait_update() trade1 = api.get_trade("1710cf5327ac435a7a97c643656412a9|1") trade2 = api.get_trade("8ca5996666ceab360512bd1311072231|2") self.assertAlmostEqual(1586414355666978000 / 1e9, trade1.trade_date_time / 1e9, places=1) self.assertAlmostEqual(1586414355667884000 / 1e9, trade2.trade_date_time / 1e9, places=1) del trade1["trade_date_time"] del trade2["trade_date_time"] self.assertEqual( str(trade1), "{'order_id': '1710cf5327ac435a7a97c643656412a9', 'trade_id': '1710cf5327ac435a7a97c643656412a9|1', 'exchange_trade_id': '1710cf5327ac435a7a97c643656412a9|1', 'exchange_id': 'DCE', 'instrument_id': 'jd2005', 'direction': 'BUY', 'offset': 'OPEN', 'price': 3317.0, 'volume': 1, 'user_id': 'TQSIM', 'commission': 6.122999999999999}" ) self.assertEqual( str(trade2), "{'order_id': '8ca5996666ceab360512bd1311072231', 'trade_id': '8ca5996666ceab360512bd1311072231|2', 'exchange_trade_id': '8ca5996666ceab360512bd1311072231|2', 'exchange_id': 'SHFE', 'instrument_id': 'cu2005', 'direction': 'BUY', 'offset': 'OPEN', 'price': 40870.0, 'volume': 2, 'user_id': 'TQSIM', 'commission': 23.189999999999998}" ) self.assertEqual(trade1.direction, "BUY") self.assertEqual(trade1.offset, "OPEN") self.assertEqual(trade1.price, 3317.0) self.assertEqual(trade1.volume, 1) self.assertEqual(trade1.commission, 6.122999999999999) self.assertEqual(trade2.direction, "BUY") self.assertEqual(trade2.offset, "OPEN") self.assertEqual(trade2.price, 40870.0) self.assertEqual(trade2.volume, 2) self.assertEqual(trade2.commission, 23.189999999999998) api.close() 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")) # 测试: 模拟账户下单 utils.RD = random.Random(4) api = TqApi(_ins_url=self.ins_url_2019_07_03, _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() # 期权模拟交易盘中测试 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语句的内容 utils.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_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")) # 测试: 模拟账户 utils.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() def test_get_account_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_account_simulate_option.script.lzma")) # 测试: 获取数据 api = TqApi(_ins_url=self.ins_url_2020_04_02, _td_url=self.td_url, _md_url=self.md_url) utils.RD = random.Random(4) order1 = api.insert_order("CZCE.SR007C5600", "SELL", "OPEN", 2, limit_price=50) order2 = api.insert_order("DCE.m2007-P-2900", "BUY", "OPEN", 3, limit_price=180) while order1.status == "ALIVE" or order2.status == "ALIVE": api.wait_update() account = api.get_account() # 测试脚本重新生成后,数据根据实际情况有变化 self.assertEqual( str(account), "{'currency': 'CNY', 'pre_balance': 10000000.0, 'static_balance': 10000000.0, 'balance': 9998650.0, 'available': 9989752.8, 'ctp_balance': nan, 'ctp_available': nan, 'float_profit': -300.0, 'position_profit': 0.0, 'close_profit': 0.0, 'frozen_margin': 0.0, 'margin': 4797.200000000001, 'frozen_commission': 0.0, 'commission': 50.0, 'frozen_premium': 0.0, 'premium': -5400.0, 'deposit': 0.0, 'withdraw': 0.0, 'risk_ratio': 0.00047978477094407754, 'market_value': 4100.0}" ) self.assertEqual(account.currency, "CNY") self.assertEqual(account.pre_balance, 10000000.0) self.assertEqual(account.balance, 9998650.0) self.assertEqual(account["commission"], 50.0) self.assertEqual(account["margin"], 4797.200000000001) self.assertEqual(account.position_profit, 0.0) self.assertEqual(account.available, 9989752.8) self.assertNotEqual(account.ctp_balance, account.ctp_balance) # nan self.assertEqual(account.float_profit, -300.0) self.assertEqual(account.position_profit, 0.0) self.assertEqual(account.margin, 4797.200000000001) self.assertEqual(account.commission, 50.0) self.assertEqual(account.premium, -5400.0) self.assertEqual(account.risk_ratio, 0.00047978477094407754) self.assertEqual(account.market_value, 4100.0) 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=10) order4 = api.insert_order("CZCE.SR007C5600", "SELL", "OPEN", 3) # 只有郑商所支持期权市价单 order5 = api.insert_order("DCE.m2007-P-2900", "BUY", "OPEN", 1) # 只有郑商所支持期权市价单 while order1.status == "ALIVE" or order2.status == "ALIVE" or order3.status == "ALIVE" or order4.status == "ALIVE" or order5.status == "ALIVE": api.wait_update() self.assertEqual(order4.volume_left, 0) self.assertEqual(order5.volume_left, 1) position = api.get_position("CZCE.SR007C5600") position2 = api.get_position("DCE.m2007-P-2900") self.assertEqual(0, position2.pos_long) self.assertEqual(0, position2.pos_short) # 测试脚本重新生成后,数据根据实际情况有变化 self.assertEqual( "{'exchange_id': 'CZCE', 'instrument_id': 'SR007C5600', 'pos_long_his': 0, 'pos_long_today': 5, 'pos_short_his': 0, 'pos_short_today': 6, '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': 6, 'volume_short_his': 0, 'volume_short': 6, 'volume_short_frozen_today': 0, 'volume_short_frozen_his': 0, 'volume_short_frozen': 0, 'open_price_long': 55.0, 'open_price_short': 22.5, 'open_cost_long': 2750.0, 'open_cost_short': 1350.0, 'position_price_long': 55.0, 'position_price_short': 22.5, 'position_cost_long': 2750.0, 'position_cost_short': 1350.0, 'float_profit_long': -1000.0, 'float_profit_short': -750.0, 'float_profit': -1750.0, 'position_profit_long': 0.0, 'position_profit_short': 0.0, 'position_profit': 0.0, 'margin_long': 0.0, 'margin_short': 8156.4000000000015, 'margin': 8156.4000000000015, 'market_value_long': 1750.0, 'market_value_short': -2100.0, 'market_value': -350.0, 'last_price': 35.0}", str(position)) self.assertEqual(-1, position.pos) self.assertEqual(5, position.pos_long) self.assertEqual(6, 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, 6) 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, 6) self.assertEqual(position.volume_short_his, 0) self.assertEqual(position.volume_short, 6) 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, 22.5) self.assertEqual(position.open_cost_long, 2750.0) self.assertEqual(position.open_cost_short, 1350.0) self.assertEqual(position.position_price_long, 55.0) self.assertEqual(position.position_price_short, 22.5) self.assertEqual(position.position_cost_long, 2750.0) self.assertEqual(position.position_cost_short, 1350.0) self.assertEqual(position.float_profit_long, -1000.0) self.assertEqual(position.float_profit_short, -750.0) self.assertEqual(position.float_profit, -1750.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, 8156.4000000000015) self.assertEqual(position.margin, 8156.4000000000015) self.assertEqual(position.market_value_long, 1750.0) self.assertEqual(position.market_value_short, -2100.0) self.assertEqual(position.market_value, -350.0) self.assertEqual(position.last_price, 35.0) # 其他取值方式测试 self.assertEqual(position["pos_long_today"], 5) self.assertEqual(position["pos_short_today"], 6) self.assertEqual(position["volume_long_his"], 0) self.assertEqual(position["volume_long"], 5) api.close() def test_get_trade_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_trade_simulate_option.script.lzma")) # 测试: 模拟账户 utils.RD = random.Random(4) 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", "SELL", "OPEN", 1, limit_price=50) order2 = api.insert_order("DCE.m2007-P-2900", "BUY", "OPEN", 2, limit_price=180) while order1.status == "ALIVE" or order2.status == "ALIVE": api.wait_update() trade1 = api.get_trade("1710cf5327ac435a7a97c643656412a9|1") trade2 = api.get_trade("8ca5996666ceab360512bd1311072231|2") self.assertAlmostEqual(1586501231007428000 / 1e9, trade1.trade_date_time / 1e9, places=1) self.assertAlmostEqual(1586501233361505000 / 1e9, trade2.trade_date_time / 1e9, places=1) del trade1["trade_date_time"] del trade2["trade_date_time"] self.assertEqual( str(trade1), "{'order_id': '1710cf5327ac435a7a97c643656412a9', 'trade_id': '1710cf5327ac435a7a97c643656412a9|1', 'exchange_trade_id': '1710cf5327ac435a7a97c643656412a9|1', 'exchange_id': 'CZCE', 'instrument_id': 'SR007C5600', 'direction': 'SELL', 'offset': 'OPEN', 'price': 50.0, 'volume': 1, 'user_id': 'TQSIM', 'commission': 10}" ) self.assertEqual( str(trade2), "{'order_id': '8ca5996666ceab360512bd1311072231', 'trade_id': '8ca5996666ceab360512bd1311072231|2', 'exchange_trade_id': '8ca5996666ceab360512bd1311072231|2', 'exchange_id': 'DCE', 'instrument_id': 'm2007-P-2900', 'direction': 'BUY', 'offset': 'OPEN', 'price': 180.0, 'volume': 2, 'user_id': 'TQSIM', 'commission': 20}" ) self.assertEqual(trade1.direction, "SELL") self.assertEqual(trade1.offset, "OPEN") self.assertEqual(trade1.price, 50.0) self.assertEqual(trade1.volume, 1) self.assertEqual(trade1.commission, 10) self.assertEqual(trade2.direction, "BUY") self.assertEqual(trade2.offset, "OPEN") self.assertEqual(trade2.price, 180.0) self.assertEqual(trade2.volume, 2) self.assertEqual(trade2.commission, 20) api.close()
class TestMdBasic(unittest.TestCase): """ 行情部分基本功能测试. 测试TqApi行情相关函数, 以及TqApi与行情服务器交互是否符合设计预期 """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() # 获取行情测试 # @unittest.skip("无条件跳过") def test_get_quote_normal(self): """ 获取行情报价 """ # 预设服务器端响应 self.mock.run("test_md_basic_get_quote_normal.script") # 获取行情 api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) q = api.get_quote("SHFE.cu1909") self.assertEqual( str(q), "{'datetime': '2019-09-16 14:59:59.999500', 'ask_price1': 47650.0, 'ask_volume1': 10, 'bid_price1': 47570.0, 'bid_volume1': 5, 'last_price': 47580.0, 'highest': 47860.0, 'lowest': 47580.0, 'open': 47860.0, 'close': 47580.0, 'average': 47732.35, 'volume': 9020, 'amount': 2152729000.0, 'open_interest': 6940, 'settlement': 47730.0, 'upper_limit': 49650.0, 'lower_limit': 44920.0, 'pre_open_interest': 13260, 'pre_settlement': 47290.0, 'pre_close': 47590.0, 'price_tick': 10, 'price_decs': 0, 'volume_multiple': 5, 'max_limit_order_volume': 500, 'max_market_order_volume': 0, 'min_limit_order_volume': 0, 'min_market_order_volume': 0, 'underlying_symbol': '', 'strike_price': nan, 'change': nan, 'change_percent': nan, 'expired': False, 'margin': 16233.000000000002, 'commission': 11.594999999999999, 'instrument_id': 'SHFE.cu1909', 'ask_price5': '-', 'ask_volume5': 0, 'ask_price4': 49250.0, 'ask_volume4': 50, 'ask_price3': 47990.0, 'ask_volume3': 5, 'ask_price2': 47730.0, 'ask_volume2': 10, 'bid_price2': 46560.0, 'bid_volume2': 100, 'bid_price3': 45650.0, 'bid_volume3': 270, 'bid_price4': 44920.0, 'bid_volume4': 5, 'bid_price5': '-', 'bid_volume5': 0}" ) self.assertEqual(q.datetime, "2019-09-16 14:59:59.999500") self.assertEqual(q.ask_price1, 47650.0) self.assertEqual(q.ask_volume1, 10) self.assertEqual(q.bid_price1, 47570.0) self.assertEqual(q.bid_volume1, 5) self.assertEqual(q.last_price, 47580.0) self.assertEqual(q.highest, 47860.0) self.assertEqual(q.lowest, 47580.0) self.assertEqual(q.open, 47860.0) self.assertEqual(q.close, 47580.0) self.assertEqual(q.average, 47732.35) self.assertEqual(q.volume, 9020) self.assertEqual(q.amount, 2152729000.0) self.assertEqual(q.open_interest, 6940) self.assertEqual(q.settlement, 47730.0) self.assertEqual(q.upper_limit, 49650.0) self.assertEqual(q.lower_limit, 44920) self.assertEqual(q.pre_open_interest, 13260) self.assertEqual(q.pre_settlement, 47290.0) self.assertEqual(q.pre_close, 47590.0) # 其他取值方式 self.assertEqual(q["pre_close"], 47590.0) self.assertEqual(q.get("pre_settlement"), 47290.0) self.assertEqual(q.get("highest"), 47860.0) self.assertEqual(q.get("lowest"), 47580.0) self.assertEqual(q["open"], 47860.0) self.assertEqual(q["close"], 47580.0) # 报错测试 self.assertRaises(Exception, api.get_quote, "SHFE.au1999") self.assertRaises(KeyError, q.__getitem__, "ask_price6") api.close() # @unittest.skip("无条件跳过") def test_get_kline_serial(self): """ 获取K线数据 """ # 预设服务器端响应 self.mock.run("test_md_basic_get_kline_serial.script") # 测试: 获取K线数据 TqApi.RD = random.Random(1) api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) klines = api.get_kline_serial("SHFE.cu1909", 10) self.assertEqual(klines.iloc[-1].close, 47580.0) self.assertEqual(klines.iloc[-1].id, 660788) self.assertEqual(klines.iloc[-2].id, 660787) self.assertEqual(klines.iloc[-1].datetime, 1.56861719e+18) self.assertEqual(klines.iloc[-1].open, 47580) self.assertEqual(klines.iloc[-1].volume, 0.0) self.assertEqual(klines.iloc[-1].open_oi, 6940.0) self.assertEqual(klines.iloc[-1].duration, 10) # 其他取值方式 self.assertEqual(klines.duration.iloc[-1], 10) self.assertEqual(klines.iloc[-1]["duration"], 10) self.assertEqual(klines["duration"].iloc[-1], 10) # 报错测试 self.assertRaises(Exception, api.get_kline_serial, "SHFE.au1999", 10) self.assertRaises(AttributeError, klines.iloc[-1].__getattribute__, "dur") self.assertRaises(KeyError, klines.iloc[-1].__getitem__, "dur") api.close() # @unittest.skip("无条件跳过") def test_get_tick_serial(self): """ 获取tick数据 """ # 预设服务器端响应 self.mock.run("test_md_basic_get_tick_serial.script") # 测试: 获取tick数据 TqApi.RD = random.Random(2) api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) ticks = api.get_tick_serial("SHFE.cu1909") self.assertEqual(ticks.iloc[-1].id, 2822951.0) self.assertEqual(ticks.iloc[-1].datetime, 1.5686171999995e+18) self.assertEqual(ticks.iloc[-1].last_price, 47580) self.assertEqual(ticks.iloc[-1].average, 47732.3516) self.assertEqual(ticks.iloc[-1].highest, 47860) self.assertEqual(ticks.iloc[-1].lowest, 47580) self.assertEqual(ticks.iloc[-1].ask_price1, 47650) self.assertEqual(ticks.iloc[-1].ask_volume1, 10) self.assertEqual(ticks.iloc[-1].bid_price1, 47570) self.assertEqual(ticks.iloc[-1].bid_volume1, 5) self.assertEqual(ticks.iloc[-1].volume, 9020) self.assertEqual(ticks.iloc[-1].amount, 2152729000.0) self.assertEqual(ticks.iloc[-1].open_interest, 6940) self.assertEqual(ticks.iloc[-1].duration, 0) # 其他调用方式 self.assertEqual(ticks.open_interest.iloc[-1], 6940) self.assertEqual(ticks["open_interest"].iloc[-2], 6940) self.assertEqual(ticks.iloc[-1]["ask_price1"], 47650) # 报错测试 self.assertRaises(Exception, api.get_tick_serial, "SHFE.au1999") self.assertRaises(AttributeError, ticks.iloc[-1].__getattribute__, "dur") self.assertRaises(KeyError, ticks.iloc[-1].__getitem__, "dur") api.close()
class TestTdTrade(unittest.TestCase): """ 实盘账户下,insert_order 各种情况测试 """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer(td_url_character="q7.htfutures.com") self.ins_url_2020_06_16 = "http://127.0.0.1:5000/t/md/symbols/2020-06-16.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() def test_insert_order_shfe_anyprice(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_shfe_anyprice.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) # 测试 with self.assertRaises(Exception): with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("SHFE.au2012", "BUY", "OPEN", 1) def test_insert_order_shfe_limit_fok(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_shfe_limit_fok.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("SHFE.rb2010", "BUY", "OPEN", 2, limit_price=3500, advanced="FOK", order_id="PYSDK_insert_SHFE_limit_FOK") while True: api.wait_update() if order1.status == "FINISHED": break self.assertEqual("PYSDK_insert_SHFE_limit_FOK", order1.order_id) self.assertEqual(" 25169789", order1.exchange_order_id) self.assertEqual("SHFE", order1.exchange_id) self.assertEqual("rb2010", order1.instrument_id) self.assertEqual("BUY", order1.direction) self.assertEqual("OPEN", order1.offset) self.assertEqual(2, order1.volume_orign) self.assertEqual(2, order1.volume_left) self.assertEqual(3500.0, order1.limit_price) self.assertEqual(1593585599000000000, order1.insert_date_time) self.assertEqual("FINISHED", order1.status) self.assertEqual("LIMIT", order1.price_type) self.assertEqual("ALL", order1.volume_condition) self.assertEqual("IOC", order1.time_condition) self.assertEqual("已撤单报单已提交", order1.last_msg) self.assertEqual( "{'order_id': 'PYSDK_insert_SHFE_limit_FOK', 'exchange_order_id': ' 25169789', 'exchange_id': 'SHFE', 'instrument_id': 'rb2010', 'direction': 'BUY', 'offset': 'OPEN', 'volume_orign': 2, 'volume_left': 2, 'limit_price': 3500.0, 'price_type': 'LIMIT', 'volume_condition': 'ALL', 'time_condition': 'IOC', 'insert_date_time': 1593585599000000000, 'last_msg': '已撤单报单已提交', 'status': 'FINISHED', 'seqno': 19, 'user_id': '83011119'}", str(order1)) def test_insert_order_shfe_limit_fak(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_shfe_limit_fak.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("SHFE.rb2010", "BUY", "OPEN", 2, limit_price=3500, advanced="FAK", order_id="PYSDK_insert_SHFE_limit_FAK") while True: api.wait_update() if order1.status == "FINISHED": break self.assertEqual("PYSDK_insert_SHFE_limit_FAK", order1.order_id) self.assertEqual(" 25308102", order1.exchange_order_id) self.assertEqual("SHFE", order1.exchange_id) self.assertEqual("rb2010", order1.instrument_id) self.assertEqual("BUY", order1.direction) self.assertEqual("OPEN", order1.offset) self.assertEqual(2, order1.volume_orign) self.assertEqual(2, order1.volume_left) self.assertEqual(3500.0, order1.limit_price) self.assertEqual(1593585743000000000, order1.insert_date_time) self.assertEqual("FINISHED", order1.status) self.assertEqual("LIMIT", order1.price_type) self.assertEqual("ANY", order1.volume_condition) self.assertEqual("IOC", order1.time_condition) self.assertEqual("已撤单报单已提交", order1.last_msg) self.assertEqual( "{'order_id': 'PYSDK_insert_SHFE_limit_FAK', 'exchange_order_id': ' 25308102', 'exchange_id': 'SHFE', 'instrument_id': 'rb2010', 'direction': 'BUY', 'offset': 'OPEN', 'volume_orign': 2, 'volume_left': 2, 'limit_price': 3500.0, 'price_type': 'LIMIT', 'volume_condition': 'ANY', 'time_condition': 'IOC', 'insert_date_time': 1593585743000000000, 'last_msg': '已撤单报单已提交', 'status': 'FINISHED', 'seqno': 21, 'user_id': '83011119'}", str(order1)) def test_insert_order_dec_best(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_dec_best.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) # 测试 with self.assertRaises(Exception): with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("DCE.m2009", "BUY", "OPEN", 1, limit_price="BEST", order_id="PYSDK_insert_DCE_BEST") def test_insert_order_dec_fivelevel(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_dec_fivelevel.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) # 测试 with self.assertRaises(Exception): with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order( "DCE.m2009", "BUY", "OPEN", 1, limit_price="FIVELEVEL", order_id="PYSDK_insert_DCE_FIVELEVEL") def test_insert_order_dce_anyprice(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_dce_anyprice.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("DCE.m2009", "BUY", "OPEN", 1, order_id="PYSDK_insert_DCE_any") while True: api.wait_update() if order1.status == "FINISHED": break self.assertEqual("PYSDK_insert_DCE_any", order1.order_id) self.assertEqual(" 15350014", order1.exchange_order_id) self.assertEqual("DCE", order1.exchange_id) self.assertEqual("m2009", order1.instrument_id) self.assertEqual("BUY", order1.direction) self.assertEqual("OPEN", order1.offset) self.assertEqual(1, order1.volume_orign) self.assertEqual(0, order1.volume_left) self.assertEqual(0.0, order1.limit_price) self.assertEqual(1593586583000000000, order1.insert_date_time) self.assertEqual("FINISHED", order1.status) self.assertEqual("ANY", order1.price_type) self.assertEqual("ANY", order1.volume_condition) self.assertEqual("IOC", order1.time_condition) self.assertEqual("全部成交", order1.last_msg) self.assertEqual( "{'order_id': 'PYSDK_insert_DCE_any', 'exchange_order_id': ' 15350014', 'exchange_id': 'DCE', 'instrument_id': 'm2009', 'direction': 'BUY', 'offset': 'OPEN', 'volume_orign': 1, 'volume_left': 0, 'limit_price': 0.0, 'price_type': 'ANY', 'volume_condition': 'ANY', 'time_condition': 'IOC', 'insert_date_time': 1593586583000000000, 'last_msg': '全部成交', 'status': 'FINISHED', 'seqno': 38, 'user_id': '83011119'}", str(order1)) def test_insert_order_dce_anyprice_fok(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_dce_anyprice_fok.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("DCE.m2009", "BUY", "CLOSE", 2, advanced="FOK", order_id="PYSDK_insert_DCE_any_FOK") while True: api.wait_update() if order1.status == "FINISHED": break self.assertEqual("PYSDK_insert_DCE_any_FOK", order1.order_id) self.assertEqual(" 13681949", order1.exchange_order_id) self.assertEqual("DCE", order1.exchange_id) self.assertEqual("m2009", order1.instrument_id) self.assertEqual("BUY", order1.direction) self.assertEqual("CLOSE", order1.offset) self.assertEqual(2, order1.volume_orign) self.assertEqual(0, order1.volume_left) self.assertEqual(0.0, order1.limit_price) self.assertEqual(1593657995000000000, order1.insert_date_time) self.assertEqual("FINISHED", order1.status) self.assertEqual("ANY", order1.price_type) self.assertEqual("ALL", order1.volume_condition) self.assertEqual("IOC", order1.time_condition) self.assertEqual("全部成交", order1.last_msg) self.assertEqual( "{'order_id': 'PYSDK_insert_DCE_any_FOK', 'exchange_order_id': ' 13681949', 'exchange_id': 'DCE', 'instrument_id': 'm2009', 'direction': 'BUY', 'offset': 'CLOSE', 'volume_orign': 2, 'volume_left': 0, 'limit_price': 0.0, 'price_type': 'ANY', 'volume_condition': 'ALL', 'time_condition': 'IOC', 'insert_date_time': 1593657995000000000, 'last_msg': '全部成交', 'status': 'FINISHED', 'seqno': 6, 'user_id': '83011119'}", str(order1)) def test_insert_order_dce_limit_fak(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_dce_limit_fak.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("DCE.m2009", "BUY", "OPEN", 2, limit_price=2800, advanced="FAK", order_id="PYSDK_insert_DCE_limit_FAK") while True: api.wait_update() if order1.status == "FINISHED": break self.assertEqual("PYSDK_insert_DCE_limit_FAK", order1.order_id) self.assertEqual(" 15189608", order1.exchange_order_id) self.assertEqual("DCE", order1.exchange_id) self.assertEqual("m2009", order1.instrument_id) self.assertEqual("BUY", order1.direction) self.assertEqual("OPEN", order1.offset) self.assertEqual(2, order1.volume_orign) self.assertEqual(2, order1.volume_left) self.assertEqual(2800.0, order1.limit_price) self.assertEqual(1593585989000000000, order1.insert_date_time) self.assertEqual("FINISHED", order1.status) self.assertEqual("LIMIT", order1.price_type) self.assertEqual("ANY", order1.volume_condition) self.assertEqual("IOC", order1.time_condition) self.assertEqual("已撤单", order1.last_msg) self.assertEqual( "{'order_id': 'PYSDK_insert_DCE_limit_FAK', 'exchange_order_id': ' 15189608', 'exchange_id': 'DCE', 'instrument_id': 'm2009', 'direction': 'BUY', 'offset': 'OPEN', 'volume_orign': 2, 'volume_left': 2, 'limit_price': 2800.0, 'price_type': 'LIMIT', 'volume_condition': 'ANY', 'time_condition': 'IOC', 'insert_date_time': 1593585989000000000, 'last_msg': '已撤单', 'status': 'FINISHED', 'seqno': 24, 'user_id': '83011119'}", str(order1)) def test_insert_order_dce_limit_fok(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_dce_limit_fok.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("DCE.m2009", "BUY", "OPEN", 2, limit_price=2800, advanced="FOK", order_id="PYSDK_insert_DCE_limit_FOK") while True: api.wait_update() if order1.status == "FINISHED": break self.assertEqual("PYSDK_insert_DCE_limit_FOK", order1.order_id) self.assertEqual(" 15236982", order1.exchange_order_id) self.assertEqual("DCE", order1.exchange_id) self.assertEqual("m2009", order1.instrument_id) self.assertEqual("BUY", order1.direction) self.assertEqual("OPEN", order1.offset) self.assertEqual(2, order1.volume_orign) self.assertEqual(2, order1.volume_left) self.assertEqual(2800.0, order1.limit_price) self.assertEqual(1593586120000000000, order1.insert_date_time) self.assertEqual("FINISHED", order1.status) self.assertEqual("LIMIT", order1.price_type) self.assertEqual("ALL", order1.volume_condition) self.assertEqual("IOC", order1.time_condition) self.assertEqual("已撤单", order1.last_msg) self.assertEqual( "{'order_id': 'PYSDK_insert_DCE_limit_FOK', 'exchange_order_id': ' 15236982', 'exchange_id': 'DCE', 'instrument_id': 'm2009', 'direction': 'BUY', 'offset': 'OPEN', 'volume_orign': 2, 'volume_left': 2, 'limit_price': 2800.0, 'price_type': 'LIMIT', 'volume_condition': 'ALL', 'time_condition': 'IOC', 'insert_date_time': 1593586120000000000, 'last_msg': '已撤单', 'status': 'FINISHED', 'seqno': 27, 'user_id': '83011119'}", str(order1)) def test_insert_order_dce_limit_fak1(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_dce_limit_fak1.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("DCE.m2009", "BUY", "OPEN", 1, limit_price=2890, advanced="FAK", order_id="PYSDK_insert_DCE_limit_FAK1") while True: api.wait_update() if order1.status == "FINISHED": break self.assertEqual("PYSDK_insert_DCE_limit_FAK1", order1.order_id) self.assertEqual(" 15266799", order1.exchange_order_id) self.assertEqual("DCE", order1.exchange_id) self.assertEqual("m2009", order1.instrument_id) self.assertEqual("BUY", order1.direction) self.assertEqual("OPEN", order1.offset) self.assertEqual(1, order1.volume_orign) self.assertEqual(0, order1.volume_left) self.assertEqual(2890.0, order1.limit_price) self.assertEqual(1593586261000000000, order1.insert_date_time) self.assertEqual("FINISHED", order1.status) self.assertEqual("LIMIT", order1.price_type) self.assertEqual("ANY", order1.volume_condition) self.assertEqual("IOC", order1.time_condition) self.assertEqual("全部成交", order1.last_msg) self.assertEqual( "{'order_id': 'PYSDK_insert_DCE_limit_FAK1', 'exchange_order_id': ' 15266799', 'exchange_id': 'DCE', 'instrument_id': 'm2009', 'direction': 'BUY', 'offset': 'OPEN', 'volume_orign': 1, 'volume_left': 0, 'limit_price': 2890.0, 'price_type': 'LIMIT', 'volume_condition': 'ANY', 'time_condition': 'IOC', 'insert_date_time': 1593586261000000000, 'last_msg': '全部成交', 'status': 'FINISHED', 'seqno': 30, 'user_id': '83011119'}", str(order1)) def test_insert_order_dce_limit_fok1(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_insert_order_dce_limit_fok1.script")) # 测试 account = TqAccount("H海通期货", "83011119", "********") utils.RD = random.Random(4) with TqApi(account=account, _ins_url=self.ins_url_2020_06_16, _md_url=self.md_url, _td_url=self.td_url, debug=False) as api: order1 = api.insert_order("DCE.m2009", "SELL", "OPEN", 2, limit_price=2905, advanced="FOK", order_id="PYSDK_insert_DCE_limit_FOK1") while True: api.wait_update() if order1.status == "FINISHED": break self.assertEqual("PYSDK_insert_DCE_limit_FOK1", order1.order_id) self.assertEqual(" 13619123", order1.exchange_order_id) self.assertEqual("DCE", order1.exchange_id) self.assertEqual("m2009", order1.instrument_id) self.assertEqual("SELL", order1.direction) self.assertEqual("OPEN", order1.offset) self.assertEqual(2, order1.volume_orign) self.assertEqual(0, order1.volume_left) self.assertEqual(2905.0, order1.limit_price) self.assertEqual(1593657671000000000, order1.insert_date_time) self.assertEqual("FINISHED", order1.status) self.assertEqual("LIMIT", order1.price_type) self.assertEqual("ALL", order1.volume_condition) self.assertEqual("IOC", order1.time_condition) self.assertEqual("全部成交", order1.last_msg) self.assertEqual( "{'order_id': 'PYSDK_insert_DCE_limit_FOK1', 'exchange_order_id': ' 13619123', 'exchange_id': 'DCE', 'instrument_id': 'm2009', 'direction': 'SELL', 'offset': 'OPEN', 'volume_orign': 2, 'volume_left': 0, 'limit_price': 2905.0, 'price_type': 'LIMIT', 'volume_condition': 'ALL', 'time_condition': 'IOC', 'insert_date_time': 1593657671000000000, 'last_msg': '全部成交', 'status': 'FINISHED', 'seqno': 2, 'user_id': '83011119'}", str(order1))
def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer(td_url_character="q7.htfutures.com") self.ins_url_2020_06_16 = "http://127.0.0.1:5000/t/md/symbols/2020-06-16.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/"
class TestMdBasic(unittest.TestCase): """ 测试TqApi行情相关函数基本功能, 以及TqApi与行情服务器交互是否符合设计预期 注: 1. 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2. 若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 utils.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 3. 對盤中的測試用例(即非回測):因为TqSim模拟交易 Order 的 insert_date_time 和 Trade 的 trade_date_time 不是固定值,所以改为判断范围。 盘中时:self.assertAlmostEqual(1575292560005832000 / 1e9, order1.insert_date_time / 1e9, places=1) 回测时:self.assertEqual(1575291600000000000, order1.insert_date_time) """ def setUp(self): # self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url_2019_07_03 = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): # self.ins.close() self.mock.close() # 获取行情测试 # @unittest.skip("无条件跳过") def test_get_quote_normal(self): """ 获取行情报价 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_md_basic_get_quote_normal.script.lzma")) # 获取行情 api = TqApi(_ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) q = api.get_quote("SHFE.cu1909") self.assertEqual(q.datetime, "2019-09-16 14:59:59.999500") self.assertEqual(q.ask_price1, 47650.0) self.assertEqual(q.ask_volume1, 10) self.assertEqual(q.bid_price1, 47570.0) self.assertEqual(q.bid_volume1, 5) self.assertEqual(q.last_price, 47580.0) self.assertEqual(q.highest, 47860.0) self.assertEqual(q.lowest, 47580.0) self.assertEqual(q.open, 47860.0) self.assertEqual(q.close, 47580.0) self.assertEqual(q.average, 47732.35) self.assertEqual(q.volume, 9020) self.assertEqual(q.amount, 2152729000.0) self.assertEqual(q.open_interest, 6940) self.assertEqual(q.settlement, 47730.0) self.assertEqual(q.upper_limit, 49650.0) self.assertEqual(q.lower_limit, 44920) self.assertEqual(q.pre_open_interest, 13260) self.assertEqual(q.pre_settlement, 47290.0) self.assertEqual(q.pre_close, 47590.0) self.assertEqual(q.price_tick, 10) self.assertEqual(q.price_decs, 0) self.assertEqual(q.volume_multiple, 5) self.assertEqual(q.max_limit_order_volume, 500) self.assertEqual(q.max_market_order_volume, 0) self.assertEqual(q.min_limit_order_volume, 0) self.assertEqual(q.min_market_order_volume, 0) self.assertEqual(q.underlying_symbol, "") self.assertTrue(q.strike_price != q.strike_price) # 判定nan self.assertEqual(q.expired, False) self.assertEqual(q.ins_class, "FUTURE") self.assertEqual(q.margin, 16233.000000000002) self.assertEqual(q.commission, 11.594999999999999) self.assertEqual( repr(q.trading_time.day), "[['09:00:00', '10:15:00'], ['10:30:00', '11:30:00'], ['13:30:00', '15:00:00']]" ) self.assertEqual(repr(q.trading_time.night), "[['21:00:00', '25:00:00']]") self.assertEqual(q.expire_datetime, 1568617200.0) self.assertEqual(q.delivery_month, 9) self.assertEqual(q.delivery_year, 2019) self.assertEqual(q.instrument_id, "SHFE.cu1909") self.assertEqual(q.ask_price2, 47730.0) self.assertEqual(q.ask_volume2, 10) self.assertEqual(q.ask_price3, 47990.0) self.assertEqual(q.ask_volume3, 5) self.assertEqual(q.ask_price4, 49250.0) self.assertEqual(q.ask_volume4, 50) self.assertEqual(q.ask_price5 != q.ask_price5, True) # 判断nan self.assertEqual(q.ask_volume5, 0) self.assertEqual(q.bid_price2, 46560.0) self.assertEqual(q.bid_volume2, 100) self.assertEqual(q.bid_price3, 45650.0) self.assertEqual(q.bid_volume3, 270) self.assertEqual(q.bid_price4, 44920.0) self.assertEqual(q.bid_volume4, 5) self.assertEqual(q.bid_price5 != q.bid_price5, True) self.assertEqual(q.bid_volume5, 0) # 其他取值方式 self.assertEqual(q["pre_close"], 47590.0) self.assertEqual(q.get("pre_settlement"), 47290.0) self.assertEqual(q.get("highest"), 47860.0) self.assertEqual(q.get("lowest"), 47580.0) self.assertEqual(q["open"], 47860.0) self.assertEqual(q["close"], 47580.0) # 报错测试 self.assertRaises(Exception, api.get_quote, "SHFE.au1999") self.assertRaises(KeyError, q.__getitem__, "ask_price6") api.close() def test_get_kline_serial(self): """ 获取K线数据 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_md_basic_get_kline_serial.script.lzma")) # 测试: 获取K线数据 utils.RD = random.Random(1) api = TqApi(_ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) klines = api.get_kline_serial("SHFE.cu1909", 10) self.assertEqual(klines.iloc[-1].close, 47580.0) self.assertEqual(klines.iloc[-1].id, 660788) self.assertEqual(klines.iloc[-2].id, 660787) self.assertEqual(klines.iloc[-1].datetime, 1.56861719e+18) self.assertEqual(klines.iloc[-1].open, 47580) self.assertEqual(klines.iloc[-1].volume, 0.0) self.assertEqual(klines.iloc[-1].open_oi, 6940.0) self.assertEqual(klines.iloc[-1].duration, 10) # 其他取值方式 self.assertEqual(klines.duration.iloc[-1], 10) self.assertEqual(klines.iloc[-1]["duration"], 10) self.assertEqual(klines["duration"].iloc[-1], 10) # 报错测试 self.assertRaises(Exception, api.get_kline_serial, "SHFE.au1999", 10) self.assertRaises(AttributeError, klines.iloc[-1].__getattribute__, "dur") self.assertRaises(KeyError, klines.iloc[-1].__getitem__, "dur") api.close() def test_get_tick_serial(self): """ 获取tick数据 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_md_basic_get_tick_serial.script.lzma")) # 测试: 获取tick数据 utils.RD = random.Random(2) api = TqApi(_ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) ticks = api.get_tick_serial("SHFE.cu1909") self.assertEqual(ticks.iloc[-1].id, 2822951.0) self.assertEqual(ticks.iloc[-1].datetime, 1.5686171999995e+18) self.assertEqual(ticks.iloc[-1].last_price, 47580) self.assertEqual(ticks.iloc[-1].average, 47732.3516) self.assertEqual(ticks.iloc[-1].highest, 47860) self.assertEqual(ticks.iloc[-1].lowest, 47580) self.assertEqual(ticks.iloc[-1].ask_price1, 47650) self.assertEqual(ticks.iloc[-1].ask_volume1, 10) self.assertEqual(ticks.iloc[-1].bid_price1, 47570) self.assertEqual(ticks.iloc[-1].bid_volume1, 5) self.assertEqual(ticks.iloc[-1].volume, 9020) self.assertEqual(ticks.iloc[-1].amount, 2152729000.0) self.assertEqual(ticks.iloc[-1].open_interest, 6940) self.assertEqual(ticks.iloc[-1].duration, 0) # 其他调用方式 self.assertEqual(ticks.open_interest.iloc[-1], 6940) self.assertEqual(ticks["open_interest"].iloc[-2], 6940) self.assertEqual(ticks.iloc[-1]["ask_price1"], 47650) # 报错测试 self.assertRaises(Exception, api.get_tick_serial, "SHFE.au1999") self.assertRaises(AttributeError, ticks.iloc[-1].__getattribute__, "dur") self.assertRaises(KeyError, ticks.iloc[-1].__getitem__, "dur") api.close()
class TestLib(unittest.TestCase): """ 对lib.py的测试 注: 1. 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2. 若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 utils.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 3. 對盤中的測試用例(即非回測):因为TqSim模拟交易 Order 的 insert_date_time 和 Trade 的 trade_date_time 不是固定值,所以改为判断范围。 盘中时:self.assertAlmostEqual(1575292560005832000 / 1e9, order1.insert_date_time / 1e9, places=1) 回测时:self.assertEqual(1575291600000000000, order1.insert_date_time) """ def setUp(self): # self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url_2019_12_04 = "https://openmd.shinnytech.com/t/md/symbols/2019-12-04.json" self.ins_url_2020_02_18 = "https://openmd.shinnytech.com/t/md/symbols/2020-02-18.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): # self.ins.close() self.mock.close() 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")) utils.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() def test_lib_insert_order_time_check_2(self): """ lib下单时间判断测试2 回测时间: 10:15 - 10:45 订阅合约: IF、T(无盘中休息时间),cu(有盘中休息时间) 测试: 10:15 - 10:30期间IF和T能立即下单,cu等到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_2.script.lzma")) utils.RD = random.Random(4) api = TqApi(backtest=TqBacktest( datetime.datetime(2020, 2, 17, 10, 15, 0), datetime.datetime(2020, 2, 17, 10, 45, 0)), _ins_url=self.ins_url_2020_02_18) symbol1 = "SHFE.cu2003" symbol2 = "CFFEX.T2003" symbol3 = "CFFEX.IF2003" 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 10:15 - 10:30期间IF和T能立即下单,cu等到10:30以后下单; 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( 2020, 2, 17, 10, 25): api.wait_update() self.assertEqual(len(orders), 2) self.assertEqual(position1.pos, 0) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 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) print("回测结束") api.close() def test_lib_insert_order_time_check_3(self): ''' lib下单时间判断测试3 回测时间: 第一日白盘11:30 - 第二日白盘9:40 订阅合约: IF、T(无盘中休息时间),cu(有盘中休息时间) 测试: 1 T、IF在13:00后下单,cu到13:30后下单 2 15:00 - 15:15 : T能下单,IF、cu不能下单 3 2020.2.18 交易所通知cu这段时间没有夜盘,因此之前set的手数到第二个交易日开盘后下单 4 cu在9点开盘下单,IF在9: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_3.script.lzma")) utils.RD = random.Random(4) api = TqApi(backtest=TqBacktest(datetime.datetime(2020, 2, 17, 11, 30), datetime.datetime(2020, 2, 18, 9, 40)), _ins_url=self.ins_url_2020_02_18) symbol1 = "SHFE.cu2003" symbol2 = "CFFEX.T2003" symbol3 = "CFFEX.IF2003" 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 T、IF在13:00后下单,cu到13:30后下单 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) < "2020-02-17 13:15:00.000000": api.wait_update() self.assertEqual(len(orders), 2) self.assertEqual(position1.pos, 0) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 3) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-17 13:31:00.000000": api.wait_update() self.assertEqual(len(orders), 3) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-17 13:40:00.000000": api.wait_update() self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 3) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-17 15:00:00.000000": api.wait_update() # 2 15:00 - 15:15 : T能下单,IF、cu不能下单 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) < "2020-02-17 15:13:59.000000": api.wait_update() self.assertEqual(len(orders), 4) self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 5) self.assertEqual(position3.pos, 3) # 3 2020.2.18 交易所通知cu这段时间没有夜盘,因此之前set的手数到第二个交易日开盘后下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-18 09:00:00.0000": api.wait_update() self.assertEqual(len(orders), 4) self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 5) self.assertEqual(position3.pos, 3) # 4 cu在9点开盘下单,IF在9:30开盘下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-18 09:20:00.0000": api.wait_update() self.assertEqual(len(orders), 5) self.assertEqual(position1.pos, 4) self.assertEqual(position2.pos, 5) self.assertEqual(position3.pos, 3) while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-18 09:35:00.0000": api.wait_update() self.assertEqual(len(orders), 6) self.assertEqual(position1.pos, 4) self.assertEqual(position2.pos, 5) self.assertEqual(position3.pos, 6) while True: api.wait_update() except BacktestFinished: self.assertEqual(len(orders), 6) self.assertEqual(position1.pos, 4) self.assertEqual(position2.pos, 5) self.assertEqual(position3.pos, 6) api.close() 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")) utils.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() 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")) utils.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 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")) utils.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_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")) utils.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()
class TestTdBasic(unittest.TestCase): """ 测试TqApi交易相关函数基本功能, 以及TqApi与交易服务器交互是否符合设计预期 注: 1: 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2:若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 TqApi.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url = "https://openmd.shinnytech.com/t/md/symbols/2019-07-03.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() # 模拟交易测试 # @unittest.skip("无条件跳过") def test_insert_order(self): """ 下单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "test_td_basic_insert_order_simulate.script")) # 测试: 模拟账户下单 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.jd2001", "BUY", "OPEN", 1) order2 = api.insert_order("SHFE.cu2001", "BUY", "OPEN", 2, limit_price=47550) while order1.status == "ALIVE" or order2.status == "ALIVE": api.wait_update() self.assertEqual(order1.order_id, "d95bafc8f2a4d27bdcf4bb99f4bea973") 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 != order1.limit_price, True) # 判断nan self.assertEqual(order1.price_type, "ANY") self.assertEqual(order1.volume_condition, "ANY") self.assertEqual(order1.time_condition, "IOC") self.assertEqual(order1.insert_date_time, 631123200000000000) self.assertEqual(order1.status, "FINISHED") for k, v in order1.trade_records.items(): # 模拟交易为一次性全部成交 self.assertEqual( str(v), "{'order_id': 'd95bafc8f2a4d27bdcf4bb99f4bea973', 'trade_id': 'd95bafc8f2a4d27bdcf4bb99f4bea973|1', 'exchange_trade_id': 'd95bafc8f2a4d27bdcf4bb99f4bea973|1', 'exchange_id': 'DCE', 'instrument_id': 'jd2001', 'direction': 'BUY', 'offset': 'OPEN', 'price': 4570.0, 'volume': 1, 'trade_date_time': 1568875128644000000, 'symbol': 'DCE.jd2001', 'user_id': 'TQSIM', 'commission': 6.122999999999999}" ) self.assertEqual(order2.order_id, "5c6e433715ba2bdd177219d30e7a269f") 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, 47550.0) self.assertEqual(order2.price_type, "LIMIT") self.assertEqual(order2.volume_condition, "ANY") self.assertEqual(order2.time_condition, "GFD") self.assertEqual(order2.insert_date_time, 631123200000000000) self.assertEqual(order2.status, "FINISHED") for k, v in order2.trade_records.items(): # 模拟交易为一次性全部成交 self.assertEqual( str(v), "{'order_id': '5c6e433715ba2bdd177219d30e7a269f', 'trade_id': '5c6e433715ba2bdd177219d30e7a269f|2', 'exchange_trade_id': '5c6e433715ba2bdd177219d30e7a269f|2', 'exchange_id': 'SHFE', 'instrument_id': 'cu2001', 'direction': 'BUY', 'offset': 'OPEN', 'price': 47550.0, 'volume': 2, 'trade_date_time': 1568875122000000000, 'symbol': 'SHFE.cu2001', 'user_id': 'TQSIM', 'commission': 23.189999999999998}" ) api.close() # @unittest.skip("无条件跳过") def test_cancel_order(self): """ 撤单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "test_td_basic_cancel_order_simulate.script")) # 测试: 模拟账户 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.jd2001", "BUY", "OPEN", 1, limit_price=4570) order2 = api.insert_order("SHFE.cu2001", "BUY", "OPEN", 2, limit_price=47070) api.wait_update() self.assertEqual("ALIVE", order1.status) self.assertEqual("ALIVE", order2.status) api.cancel_order(order1) api.cancel_order(order2.order_id) api.wait_update() self.assertEqual("FINISHED", order1.status) self.assertEqual("FINISHED", order2.status) api.close() # @unittest.skip("无条件跳过") def test_get_account(self): """ 获取账户资金信息 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "test_td_basic_get_account_simulate.script")) # 测试: 获取数据 api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) TqApi.RD = random.Random(4) order = api.insert_order("DCE.jd2001", "BUY", "OPEN", 1, limit_price=4570) while order.status == "ALIVE": api.wait_update() account = api.get_account() self.assertEqual( str(account), "{'currency': 'CNY', 'pre_balance': 10000000.0, 'static_balance': 10000000.0, 'balance': 9999973.877, 'available': 9997116.477, 'float_profit': -20.0, 'position_profit': -20.0, 'close_profit': 0.0, 'frozen_margin': 0.0, 'margin': 2857.4, 'frozen_commission': 0.0, 'commission': 6.122999999999999, 'frozen_premium': 0.0, 'premium': 0.0, 'deposit': 0.0, 'withdraw': 0.0, 'risk_ratio': 0.00028574074644055193}" ) self.assertEqual(account.currency, "CNY") self.assertEqual(account.pre_balance, 10000000.0) self.assertEqual(9999973.877, account.balance) self.assertEqual(6.122999999999999, account["commission"]) self.assertEqual(2857.4, account["margin"]) self.assertEqual(-20.0, account.position_profit) api.close() # @unittest.skip("无条件跳过") def test_get_position(self): """ 获取持仓 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "test_td_basic_get_position_simulate.script")) # 测试: 获取数据 api = TqApi(_ins_url=self.ins_url, _td_url=self.td_url, _md_url=self.md_url) order1 = api.insert_order("DCE.jd2001", "BUY", "OPEN", 1, limit_price=4592) order2 = api.insert_order("DCE.jd2001", "BUY", "OPEN", 3) order3 = api.insert_order("DCE.jd2001", "SELL", "OPEN", 3) while order1.status == "ALIVE" or order2.status == "ALIVE" or order3.status == "ALIVE": api.wait_update() position = api.get_position("DCE.jd2001") self.assertEqual( "{'exchange_id': 'DCE', 'instrument_id': 'jd2001', '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': 4574.75, 'open_price_short': 4568.0, 'open_cost_long': 182990.0, 'open_cost_short': 137040.0, 'position_price_long': 4574.75, 'position_price_short': 4568.0, 'position_cost_long': 182990.0, 'position_cost_short': 137040.0, 'float_profit_long': -270.0, 'float_profit_short': 0.0, 'float_profit': -270.0, 'position_profit_long': -270.0, 'position_profit_short': 0.0, 'position_profit': -270.0, 'margin_long': 11429.6, 'margin_short': 8572.2, 'margin': 20001.800000000003, 'symbol': 'DCE.jd2001', 'last_price': 4568.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, "jd2001") 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, 4574.75) self.assertEqual(position.open_price_short, 4568.0) self.assertEqual(position.open_cost_long, 182990.0) self.assertEqual(position.open_cost_short, 137040.0) self.assertEqual(position.position_price_long, 4574.75) self.assertEqual(position.position_price_short, 4568.0) self.assertEqual(position.position_cost_long, 182990.0) self.assertEqual(position.position_cost_short, 137040.0) self.assertEqual(position.float_profit_long, -270.0) self.assertEqual(position.float_profit_short, 0.0) self.assertEqual(position.float_profit, -270.0) self.assertEqual(position.position_profit_long, -270.0) self.assertEqual(position.position_profit_short, 0.0) self.assertEqual(position.position_profit, -270.0) self.assertEqual(position.margin_long, 11429.6) self.assertEqual(position.margin_short, 8572.2) self.assertEqual(position.margin, 20001.800000000003) self.assertEqual(position.symbol, "DCE.jd2001") self.assertEqual(position.last_price, 4568.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() # @unittest.skip("无条件跳过") def test_get_trade(self): """ 获取成交记录 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "test_td_basic_get_trade_simulate.script")) # 测试: 模拟账户 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.jd2001", "BUY", "OPEN", 1) order2 = api.insert_order("SHFE.cu2001", "BUY", "OPEN", 2, limit_price=47550) while order1.status == "ALIVE" or order2.status == "ALIVE": api.wait_update() trade1 = api.get_trade("b8a1abcd1a6916c74da4f9fc3c6da5d7|1") trade2 = api.get_trade("1710cf5327ac435a7a97c643656412a9|2") self.assertEqual( str(trade1), "{'order_id': 'b8a1abcd1a6916c74da4f9fc3c6da5d7', 'trade_id': 'b8a1abcd1a6916c74da4f9fc3c6da5d7|1', 'exchange_trade_id': 'b8a1abcd1a6916c74da4f9fc3c6da5d7|1', 'exchange_id': 'DCE', 'instrument_id': 'jd2001', 'direction': 'BUY', 'offset': 'OPEN', 'price': 4569.0, 'volume': 1, 'trade_date_time': 1568876399999500000, 'symbol': 'DCE.jd2001', 'user_id': 'TQSIM', 'commission': 6.122999999999999}" ) self.assertEqual( str(trade2), "{'order_id': '1710cf5327ac435a7a97c643656412a9', 'trade_id': '1710cf5327ac435a7a97c643656412a9|2', 'exchange_trade_id': '1710cf5327ac435a7a97c643656412a9|2', 'exchange_id': 'SHFE', 'instrument_id': 'cu2001', 'direction': 'BUY', 'offset': 'OPEN', 'price': 47550.0, 'volume': 2, 'trade_date_time': 1568876399999500000, 'symbol': 'SHFE.cu2001', 'user_id': 'TQSIM', 'commission': 23.189999999999998}" ) self.assertEqual(trade1.direction, "BUY") self.assertEqual(trade1.offset, "OPEN") self.assertEqual(trade1.price, 4569.0) self.assertEqual(trade1.volume, 1) self.assertEqual(trade1.trade_date_time, 1568876399999500000) self.assertEqual(trade1.commission, 6.122999999999999) self.assertEqual(trade2.direction, "BUY") self.assertEqual(trade2.offset, "OPEN") self.assertEqual(trade2.price, 47550.0) self.assertEqual(trade2.volume, 2) self.assertEqual(trade2.trade_date_time, 1568876399999500000) self.assertEqual(trade2.commission, 23.189999999999998) api.close() # @unittest.skip("无条件跳过") def test_get_order(self): """ 获取委托单信息 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "test_td_basic_get_order_simulate.script")) # 测试: 模拟账户下单 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.jd2001", "BUY", "OPEN", 1) order2 = api.insert_order("SHFE.cu2001", "SELL", "OPEN", 2, limit_price=47040) while order1.status == "ALIVE" or order2.status == "ALIVE": api.wait_update() orders = api.get_order() get_order1 = api.get_order(order1.order_id) get_order2 = api.get_order(order2.order_id) self.assertEqual( str(get_order1), "{'order_id': 'b8a1abcd1a6916c74da4f9fc3c6da5d7', 'exchange_order_id': 'b8a1abcd1a6916c74da4f9fc3c6da5d7', 'exchange_id': 'DCE', 'instrument_id': 'jd2001', 'direction': 'BUY', 'offset': 'OPEN', 'volume_orign': 1, 'volume_left': 0, 'limit_price': nan, 'price_type': 'ANY', 'volume_condition': 'ANY', 'time_condition': 'IOC', 'insert_date_time': 631123200000000000, 'last_msg': '全部成交', 'status': 'FINISHED', 'user_id': 'TQSIM', 'symbol': 'DCE.jd2001', 'frozen_margin': 0.0}" ) self.assertEqual( str(get_order2), "{'order_id': '1710cf5327ac435a7a97c643656412a9', 'exchange_order_id': '1710cf5327ac435a7a97c643656412a9', 'exchange_id': 'SHFE', 'instrument_id': 'cu2001', 'direction': 'SELL', 'offset': 'OPEN', 'volume_orign': 2, 'volume_left': 0, 'limit_price': 47040.0, 'price_type': 'LIMIT', 'volume_condition': 'ANY', 'time_condition': 'GFD', 'insert_date_time': 631123200000000000, 'last_msg': '全部成交', 'status': 'FINISHED', 'user_id': 'TQSIM', 'symbol': 'SHFE.cu2001', 'frozen_margin': 0.0}" ) self.assertEqual(get_order1.order_id, "b8a1abcd1a6916c74da4f9fc3c6da5d7") 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.assertEqual(get_order1.limit_price != get_order1.limit_price, True) # 判断nan self.assertEqual(get_order1.price_type, "ANY") self.assertEqual(get_order1.volume_condition, "ANY") self.assertEqual(get_order1.time_condition, "IOC") self.assertEqual(get_order1.insert_date_time, 631123200000000000) self.assertEqual(get_order1.last_msg, "全部成交") self.assertEqual(get_order1.status, "FINISHED") self.assertEqual(get_order1.symbol, "DCE.jd2001") self.assertEqual(get_order1.frozen_margin, 0) self.assertEqual(get_order2.order_id, "1710cf5327ac435a7a97c643656412a9") 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, 47040) self.assertEqual(get_order2.price_type, "LIMIT") self.assertEqual(get_order2.volume_condition, "ANY") self.assertEqual(get_order2.time_condition, "GFD") self.assertEqual(get_order2["insert_date_time"], 631123200000000000) self.assertEqual(get_order2["last_msg"], "全部成交") self.assertEqual(get_order2["status"], "FINISHED") self.assertEqual(get_order2.symbol, "SHFE.cu2001") self.assertEqual(get_order2.frozen_margin, 0) api.close()
class TestTdBacktest(unittest.TestCase): """ 回测时的交易测试. 注: 1. 在本地运行测试用例前需设置运行环境变量(Environment variables), 保证api中dict及set等类型的数据序列在每次运行时元素顺序一致: PYTHONHASHSEED=32 2. 若测试用例中调用了会使用uuid的功能函数时(如insert_order()会使用uuid生成order_id), 则:在生成script文件时及测试用例中都需设置 utils.RD = random.Random(x), 以保证两次生成的uuid一致, x取值范围为0-2^32 3. 對盤中的測試用例(即非回測):因为TqSim模拟交易 Order 的 insert_date_time 和 Trade 的 trade_date_time 不是固定值,所以改为判断范围。 盘中时:self.assertAlmostEqual(1575292560005832000 / 1e9, order1.insert_date_time / 1e9, places=1) 回测时:self.assertEqual(1575291600000000000, order1.insert_date_time) """ def setUp(self): self.ins = MockInsServer(5000) self.mock = MockServer() # self.tq = WebsocketServer(5300) self.ins_url_2019_07_03 = "http://127.0.0.1:5000/t/md/symbols/2019-07-03.json" self.ins_url_2019_12_04 = "http://127.0.0.1:5000/t/md/symbols/2019-12-04.json" self.ins_url_2020_02_18 = "http://127.0.0.1:5000/t/md/symbols/2020-02-18.json" self.md_url = "ws://127.0.0.1:5100/" self.td_url = "ws://127.0.0.1:5200/" def tearDown(self): self.ins.close() self.mock.close() def test_various_combinations_of_order_1(self): """ 测试 能在回测时正常使用开、平顺序的多种组合方式下单 1 单次开平 * n次 (本测试函数) 2 多次开 一次全平完 3 多次开 分多次平完 4 单次开 分多次平完 related commit: a2623aed0fd1d5e5e01c7d2452e7f7f7de999c6e """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_various_combinations_of_order_1.script.lzma")) # 测试1:单次开平 * n次 utils.RD = random.Random(4) api = TqApi( backtest=TqBacktest(start_dt=datetime.datetime(2019, 12, 10, 9), end_dt=datetime.datetime(2019, 12, 11)), _ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) symbol = "DCE.m2005" position = api.get_position(symbol) for i in range(3): order_open = api.insert_order(symbol, "BUY", "OPEN", 1) while order_open.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 1) order_close = api.insert_order(symbol, "SELL", "CLOSE", 1) while order_close.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 0) api.close() def test_various_combinations_of_order_2(self): """ 测试 能在回测时正常使用开、平顺序的多种组合方式下单 1 单次开平 * n次 2 多次开 一次全平完 (本测试函数) 3 多次开 分多次平完 4 单次开 分多次平完 related commit: a2623aed0fd1d5e5e01c7d2452e7f7f7de999c6e """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_various_combinations_of_order_2.script.lzma")) # 测试2:多次开,一次全平完 utils.RD = random.Random(4) api = TqApi( backtest=TqBacktest(start_dt=datetime.datetime(2019, 12, 10, 9), end_dt=datetime.datetime(2019, 12, 11)), _ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) symbol = "DCE.m2005" position = api.get_position(symbol) order_open1 = api.insert_order(symbol, "BUY", "OPEN", 1) order_open2 = api.insert_order(symbol, "BUY", "OPEN", 1) order_open3 = api.insert_order(symbol, "BUY", "OPEN", 1) while order_open1.status != "FINISHED" or order_open2.status != "FINISHED" or order_open3.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 3) order_close1 = api.insert_order(symbol, "SELL", "CLOSE", 3) while order_close1.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 0) api.close() def test_various_combinations_of_order_3(self): """ 测试 能在回测时正常使用开、平顺序的多种组合方式下单 1 单次开平 * n次 2 多次开 一次全平完 3 多次开 分多次平完 (本测试函数) 4 单次开 分多次平完 related commit: a2623aed0fd1d5e5e01c7d2452e7f7f7de999c6e """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_various_combinations_of_order_3.script.lzma")) # 测试3:多次开 分多次平完 utils.RD = random.Random(4) api = TqApi( backtest=TqBacktest(start_dt=datetime.datetime(2019, 12, 10, 9), end_dt=datetime.datetime(2019, 12, 11)), _ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) symbol = "DCE.m2005" position = api.get_position(symbol) t = 3 for i in range(t): order_open = api.insert_order(symbol, "BUY", "OPEN", 1) while order_open.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, i + 1) for i in range(t): order_close = api.insert_order(symbol, "SELL", "CLOSE", 1) while order_close.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, t - 1 - i) api.close() def test_various_combinations_of_order_4(self): """ 测试 能在回测时正常使用开、平顺序的多种组合方式下单 1 单次开平 * n次 2 多次开 一次全平完 3 多次开 分多次平完 4 单次开 分多次平完 (本测试函数) related commit: a2623aed0fd1d5e5e01c7d2452e7f7f7de999c6e """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_various_combinations_of_order_4.script.lzma")) # 测试4:单次开 分多次平完 utils.RD = random.Random(4) api = TqApi( backtest=TqBacktest(start_dt=datetime.datetime(2019, 12, 10, 9), end_dt=datetime.datetime(2019, 12, 11)), _ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) symbol = "DCE.m2005" position = api.get_position(symbol) trades = api.get_trade() order_open = api.insert_order(symbol, "BUY", "OPEN", 3) while order_open.status != "FINISHED": api.wait_update() self.assertEqual(position.pos, 3) for i in range(3): order_close = api.insert_order(symbol, "SELL", "CLOSE", 1) while order_close.status != "FINISHED": api.wait_update() self.assertEqual(len(trades), 4) self.assertEqual(position.pos, 0) api.close() def test_sim_insert_order_time_check_1(self): """ 模拟交易下单时间判断测试1 测试时间段: 2019.12.2(周一) 21:00 - 25:00 订阅合约的条件: 1. 无夜盘 2. 有夜盘, 在23:00结束 3. 有夜盘, 在25:00结束 测试: 1. 21:00起始时刻两个有夜盘合约下单,无夜盘合约不能下单; 2. 在正常夜盘可下单时段两个有夜盘合约能下单,无夜盘合约不能成; 3. 23:00某一夜盘合约停止交易后不能下单,另一有夜盘合约能下单; """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_sim_insert_order_time_check_1.script.lzma")) # 测试 utils.RD = random.Random(4) api = TqApi( backtest=TqBacktest(datetime.datetime(2019, 12, 2, 21, 0, 0), datetime.datetime(2019, 12, 3, 1, 0, 0)), _ins_url=self.ins_url_2019_12_04, _td_url=self.td_url, _md_url=self.md_url) # 2019.12.2周一 symbol1 = "DCE.jd2002" # 无夜盘 symbol2 = "SHFE.rb2002" # 夜盘23点结束 symbol3 = "SHFE.cu2002" # 夜盘凌晨1点结束 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) try: # 1 回测起始时间(21:00:00)下单 order1 = api.insert_order(symbol=symbol1, direction="BUY", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.order_id, "8534f45738d048ec0f1099c6c3e1b258") self.assertEqual(order1.direction, 'BUY') self.assertEqual(order1.offset, 'OPEN') self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order1.limit_price, 3963.0) self.assertEqual(order1.price_type, 'LIMIT') self.assertEqual(order1.volume_condition, 'ANY') self.assertEqual(order1.time_condition, 'GFD') self.assertEqual(1575291600000000000, order1.insert_date_time) self.assertEqual(order2.order_id, "c79d679346d4ac7a5c3902b38963dc6e") 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, 3522.0) self.assertEqual(order2.price_type, 'LIMIT') self.assertEqual(order2.volume_condition, 'ANY') self.assertEqual(order2.time_condition, 'GFD') self.assertEqual(1575291600000000000, order2.insert_date_time) self.assertEqual(order3.order_id, "43000de01b2ed40ed3addccb2c33be0a") 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, 47390.0) self.assertEqual(order3.price_type, 'LIMIT') self.assertEqual(order3.volume_condition, 'ANY') self.assertEqual(order3.time_condition, 'GFD') self.assertEqual(1575291600000000000, order3.insert_date_time) # 2 正常夜盘时间下单 while datetime.datetime.strptime(quote3.datetime, "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime(2019, 12, 2, 21, 15): api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="BUY", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1575292559999999000, order1.insert_date_time) self.assertEqual(1575292559999999000, order2.insert_date_time) self.assertEqual(1575292559999999000, order3.insert_date_time) # 3 23:00rb2002停止交易后不能下单,cu2002能下单; while datetime.datetime.strptime(quote3.datetime, "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime(2019, 12, 2, 23, 0, 0): api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="BUY", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 2) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1575298859999999000, order1.insert_date_time) self.assertEqual(1575298859999999000, order2.insert_date_time) self.assertEqual(1575298859999999000, order3.insert_date_time) while True: api.wait_update() except BacktestFinished: self.assertEqual(position1.pos, 0) self.assertEqual(position2.pos, 4) self.assertEqual(position3.pos, 9) api.close() def test_sim_insert_order_time_check_2(self): """ 模拟交易下单时间判断测试2 测试时间段: 2020.2.17(周一) 10:15 - 10:45 订阅合约的条件: IF、T(无盘中休息时间),cu(有盘中休息时间) 测试: 1. 10:15 - 10:30期间 IF和T能下单,cu不能下单 2. 10:15 - 10:30之间 IF、T能下单 3. 10:30 - 10:45之间 IF、T、cu都能下单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_sim_insert_order_time_check_2.script.lzma")) # 测试 utils.RD = random.Random(4) api = TqApi( backtest=TqBacktest(datetime.datetime(2020, 2, 17, 10, 15, 0), datetime.datetime(2020, 2, 17, 10, 45, 0)), _ins_url=self.ins_url_2020_02_18, _td_url=self.td_url, _md_url=self.md_url) symbol1 = "SHFE.cu2003" symbol2 = "CFFEX.T2003" symbol3 = "CFFEX.IF2003" 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) try: # 1 10:15 - 10:30期间IF和T能下单,cu不能下单 order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1581905700000000000, order1.insert_date_time) self.assertEqual(1581905700000000000, order2.insert_date_time) self.assertEqual(1581905700000000000, order3.insert_date_time) # 2 10:15 - 10:30之间 IF、T能下单; while datetime.datetime.strptime(quote3.datetime, "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime(2020, 2, 17, 10, 20): api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="BUY", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1581906059999999000, order1.insert_date_time) self.assertEqual(1581906059999999000, order2.insert_date_time) self.assertEqual(1581906059999999000, order3.insert_date_time) # 3 10:30 - 10:45之间 IF、T、cu都能下单; while datetime.datetime.strptime(quote3.datetime, "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime(2020, 2, 17, 10, 30): api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="BUY", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1581906659999999000, order1.insert_date_time) self.assertEqual(1581906659999999000, order2.insert_date_time) self.assertEqual(1581906659999999000, order3.insert_date_time) while True: api.wait_update() except BacktestFinished: self.assertEqual(position1.pos, 1) self.assertEqual(position2.pos, 6) self.assertEqual(position3.pos, 9) api.close() def test_sim_insert_order_time_check_3(self): """ 模拟交易下单时间判断测试3 测试时间段: 2020.2.17(周一) 10:29:29 - 15:18 订阅合约条件: IF、T(无盘中休息时间),cu(有盘中休息时间) 测试: 1. 10:29:29 IF、T能下单, cu不能下单 2. 10:30 之后都能下单 3. 11:29:29.999999 能下单 4. 13:00 之后T、IF能下单,cu不能下单 5. 13:30 之后都能下单 6. 15:00 - 15:15 : T能下单,IF、cu不能下单; 7. 15:14:59 只有T2003能下单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_sim_insert_order_time_check_3.script.lzma")) # 测试 utils.RD = random.Random(4) api = TqApi( backtest=TqBacktest(datetime.datetime(2020, 2, 17, 10, 29, 29), datetime.datetime(2020, 2, 17, 15, 18, 0)), _ins_url=self.ins_url_2020_02_18) # 2019.12.2周一 symbol1 = "SHFE.cu2003" symbol2 = "CFFEX.T2003" symbol3 = "CFFEX.IF2003" 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) try: # 1 10:29:29 IF、T能下单, cu不能下单 order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1581906569000000000, order1.insert_date_time) self.assertEqual(1581906569000000000, order2.insert_date_time) self.assertEqual(1581906569000000000, order3.insert_date_time) # 2 10:30 之后都能下单; while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-17 10:30:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1581906659999999000, order1.insert_date_time) self.assertEqual(1581906659999999000, order2.insert_date_time) self.assertEqual(1581906659999999000, order3.insert_date_time) # 3 11:29:29.999999 能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) != "2020-02-17 11:29:59.999999": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.bid_price1) # 使用quote1.bid_price1使其立即成交 order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1581910199999999000, order1.insert_date_time) self.assertEqual(1581910199999999000, order2.insert_date_time) self.assertEqual(1581910199999999000, order3.insert_date_time) # 4 13:00 之后T、IF能下单,cu不能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-17 13:00:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1581915839999999000, order1.insert_date_time) self.assertEqual(1581915839999999000, order2.insert_date_time) self.assertEqual(1581915839999999000, order3.insert_date_time) # 5 13:30 之后都能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-17 13:30:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1581917459999999000, order1.insert_date_time) self.assertEqual(1581917459999999000, order2.insert_date_time) self.assertEqual(1581917459999999000, order3.insert_date_time) # 6 15:00 - 15:15 : T能下单,IF、cu不能下单; while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2020-02-17 15:00:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 3) self.assertEqual(1581922859999999000, order1.insert_date_time) self.assertEqual(1581922859999999000, order2.insert_date_time) self.assertEqual(1581922859999999000, order3.insert_date_time) # 7 15:14:59 只有T2003能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) != "2020-02-17 15:14:59.999999": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 3) self.assertEqual(1581923699999999000, order1.insert_date_time) self.assertEqual(1581923699999999000, order2.insert_date_time) self.assertEqual(1581923699999999000, order3.insert_date_time) while True: api.wait_update() except BacktestFinished: self.assertEqual(position1.pos, -3) self.assertEqual(position2.pos, 14) self.assertEqual(position3.pos, 15) api.close() def test_sim_insert_order_time_check_4(self): """ 模拟交易下单时间判断测试4 测试时间段: 交易日(datetime.date)为周一, 夜盘从周五21点到周六凌晨1点 订阅合约: cu(有夜盘,凌晨1点结束夜盘), rb(夜盘23点结束), jd(无夜盘) 测试: 1. 回测刚开始:current_datetime 为 18:00 , 都无法下单 2. 周五晚21:00之后: cu和rb能下单 3. 周五23点到周六凌晨1点前:cu能下单 4. 周一早9点后都能下单 5. 周一晚21点后cu和rb能下单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_sim_insert_order_time_check_4.script.lzma")) utils.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) 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) try: # 1 回测刚开始:current_datetime 为 18:00 , 都无法下单 order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 2) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 3) self.assertEqual(1575021600000000000, order1.insert_date_time) self.assertEqual(1575021600000000000, order2.insert_date_time) self.assertEqual(1575021600000000000, order3.insert_date_time) # 2 周五晚21:00之后: cu和rb能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-11-29 21:00:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 3) self.assertEqual(1575032459999999000, order1.insert_date_time) self.assertEqual(1575032459999999000, order2.insert_date_time) self.assertEqual(1575032459999999000, order3.insert_date_time) # 3 周六凌晨1点前:cu能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-11-30 00:01:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 2) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 3) self.assertEqual(1575043319999999000, order1.insert_date_time) self.assertEqual(1575043319999999000, order2.insert_date_time) self.assertEqual(1575043319999999000, order3.insert_date_time) # 4 周一早9点后都能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-02 09:00:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1575248459999999000, order1.insert_date_time) self.assertEqual(1575248459999999000, order2.insert_date_time) self.assertEqual(1575248459999999000, order3.insert_date_time) # 5 周一晚21点后cu和rb能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-02 21:00:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="BUY", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 3) self.assertEqual(1575291659999999000, order1.insert_date_time) self.assertEqual(1575291659999999000, order2.insert_date_time) self.assertEqual(1575291659999999000, order3.insert_date_time) while True: api.wait_update() except BacktestFinished: self.assertEqual(position1.pos, -2) self.assertEqual(position2.pos, 6) self.assertEqual(position3.pos, 3) api.close() def test_sim_insert_order_time_check_5(self): """ 模拟交易下单时间判断测试5 测试时间段: 交易日(datetime.date)在非周一,订阅有夜盘合约,判断其可交易时间段 合约: cu(有夜盘,凌晨1点结束夜盘), rb(夜盘23点结束), jd(无夜盘) 测试: 1 回测刚开始:current_datetime 为 18:00 , 都无法下单 2 前一日21点以后rb、cu能下单 3 本交易日9:00后都能下单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_sim_insert_order_time_check_5.script.lzma")) utils.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) 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) try: # 1 回测刚开始:current_datetime 为 18:00 , 都无法下单 order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 1) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 2) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 3) self.assertEqual(1575280800000000000, order1.insert_date_time) self.assertEqual(1575280800000000000, order2.insert_date_time) self.assertEqual(1575280800000000000, order3.insert_date_time) # 2 前一日21点以后rb、cu能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-02 21:00:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="BUY", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 3) self.assertEqual(1575291659999999000, order1.insert_date_time) self.assertEqual(1575291659999999000, order2.insert_date_time) self.assertEqual(1575291659999999000, order3.insert_date_time) # 3 本交易日9:00后都能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-03 09:00:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="BUY", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1575334859999999000, order1.insert_date_time) self.assertEqual(1575334859999999000, order2.insert_date_time) self.assertEqual(1575334859999999000, order3.insert_date_time) while True: api.wait_update() except BacktestFinished: self.assertEqual(position1.pos, 2) self.assertEqual(position2.pos, 4) self.assertEqual(position3.pos, 3) api.close() def test_sim_insert_order_time_check_6(self): """ 模拟交易下单时间判断测试6 测试: 限价单,直到交易日结束都不能成交: 预期交易日结束撤单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_sim_insert_order_time_check_6.script.lzma")) # 测试: utils.RD = random.Random(4) api = TqApi(backtest=TqBacktest(datetime.datetime(2019, 12, 2, 10, 31, 00), datetime.datetime(2019, 12, 3)), _ins_url=self.ins_url_2019_12_04) symbol = "DCE.m2009" order1 = api.insert_order(symbol=symbol, direction="BUY", offset="OPEN", volume=5, limit_price=2750) # 到交易日结束都无法成交 order2 = api.insert_order(symbol=symbol, direction="BUY", offset="OPEN", volume=3) try: while True: api.wait_update() except BacktestFinished: self.assertEqual(order1.status, "FINISHED") self.assertEqual(order1.volume_orign, 5) self.assertEqual(order1.volume_left, 5) self.assertEqual(order2.status, "FINISHED") self.assertEqual(order2.volume_orign, 3) self.assertEqual(order2.volume_left, 0) self.assertEqual(order1.last_msg, "交易日结束,自动撤销当日有效的委托单(GFD)") api.close() def test_sim_insert_order_time_check_7(self): """ 模拟交易下单时间判断测试7 订阅合约: 订阅周六有行情的和周六无行情的 测试: (回测从周六开始) 1 回测刚开始:current_datetime 为 0:00 , 只有cu能下单 2 白盘开始后,都能下单 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run(os.path.join(dir_path, "log_file", "test_sim_insert_order_time_check_7.script.lzma")) utils.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) try: # 1 回测刚开始:current_datetime 为 0:00 , 只有cu能下单 order1 = api.insert_order(symbol=symbol1, direction="SELL", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 2) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 3) self.assertEqual(1575043200000000000, order1.insert_date_time) self.assertEqual(1575043200000000000, order2.insert_date_time) self.assertEqual(1575043200000000000, order3.insert_date_time) # 2 白盘开始后,都能下单 while max(quote1.datetime, quote2.datetime, quote3.datetime) < "2019-12-02 09:00:00.000000": api.wait_update() order1 = api.insert_order(symbol=symbol1, direction="BUY", offset="OPEN", volume=1, limit_price=quote1.last_price) order2 = api.insert_order(symbol=symbol2, direction="BUY", offset="OPEN", volume=2, limit_price=quote2.last_price) order3 = api.insert_order(symbol=symbol3, direction="BUY", offset="OPEN", volume=3, limit_price=quote3.last_price) while order1.status != "FINISHED" or order2.status != "FINISHED" or order3.status != "FINISHED": api.wait_update() self.assertEqual(order1.volume_orign, 1) self.assertEqual(order1.volume_left, 0) self.assertEqual(order2.volume_orign, 2) self.assertEqual(order2.volume_left, 0) self.assertEqual(order3.volume_orign, 3) self.assertEqual(order3.volume_left, 0) self.assertEqual(1575248459999999000, order1.insert_date_time) self.assertEqual(1575248459999999000, order2.insert_date_time) self.assertEqual(1575248459999999000, order3.insert_date_time) while True: api.wait_update() except BacktestFinished: self.assertEqual(position1.pos, 0) self.assertEqual(position2.pos, 2) self.assertEqual(position3.pos, 3) api.close()