Пример #1
0
 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/"
Пример #2
0
 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/"
Пример #3
0
 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/"
Пример #4
0
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()
Пример #5
0
 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/"
Пример #6
0
 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/"
Пример #7
0
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()
Пример #8
0
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")
Пример #9
0
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()
Пример #10
0
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()
Пример #11
0
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)
Пример #12
0
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()
Пример #13
0
        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))
Пример #14
0
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()
Пример #15
0
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()
Пример #16
0
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()
Пример #17
0
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()
Пример #18
0
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))
Пример #19
0
 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/"
Пример #20
0
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()
Пример #21
0
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()
Пример #22
0
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()
Пример #23
0
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()