示例#1
0
class Turtle:
    def __init__(self,
                 account_id,
                 symbol,
                 donchian_channel_open_position=20,
                 donchian_channel_stop_profit=10,
                 atr_day_length=20):
        self.account_id = account_id
        self.symbol = symbol  # 合约代码
        self.donchian_channel_open_position = donchian_channel_open_position  # 唐奇安通道的天数周期(开仓)
        self.donchian_channel_stop_profit = donchian_channel_stop_profit  # 唐奇安通道的天数周期(止盈)
        self.atr_day_length = atr_day_length  # ATR计算所用天数
        self.state = {
            "position": 0,  # 本策略净持仓数(正数表示多头,负数表示空头,0表示空仓)
            "last_price": float("nan"),  # 上次调仓价
        }

        self.n = 0
        self.unit = 0
        self.donchian_channel_high = 0
        self.donchian_channel_low = 0

        self.api = TqApi(self.account_id)
        self.quote = self.api.get_quote(self.symbol)
        # 由于ATR是路径依赖函数,因此使用更长的数据序列进行计算以便使其值稳定下来
        kline_length = max(donchian_channel_open_position + 1,
                           donchian_channel_stop_profit + 1,
                           atr_day_length * 5)
        self.klines = self.api.get_kline_serial(self.symbol,
                                                24 * 60 * 60,
                                                data_length=kline_length)
        self.account = self.api.get_account()
        self.target_pos = TargetPosTask(self.api,
                                        self.symbol,
                                        init_pos=self.state["position"])

    def recalc_paramter(self):
        try:
            df = self.klines.to_dataframe()
            # 本交易日的平均真实波幅(N值)
            self.n = talib.ATR(df["high"],
                               df["low"],
                               df["close"],
                               timeperiod=self.atr_day_length).iloc[-1]
            # 买卖单位
            self.unit = int((self.account["balance"] * 0.01) /
                            (self.quote["volume_multiple"] * self.n))
            print('atr:', self.n, "  unit:", self.unit)

            # 唐奇安通道上轨:前N个交易日的最高价
            self.donchian_channel_high = max(
                self.klines.high[-self.donchian_channel_open_position - 1:-1])
            # 唐奇安通道下轨:前N个交易日的最低价
            self.donchian_channel_low = min(
                self.klines.low[-self.donchian_channel_open_position - 1:-1])
            print("唐其安通道上下轨:", self.donchian_channel_high,
                  self.donchian_channel_low)
        except Exception:  # 若尚未接收到数据, 即数据为NaN, 则在ATR或unit计算时会报错
            return False
        return True

    def set_position(self, pos):
        self.state["position"] = pos
        self.state["last_price"] = self.quote["last_price"]
        self.target_pos.set_target_volume(self.state["position"])

    def try_open(self):
        """开仓策略"""
        while self.state["position"] == 0:
            self.api.wait_update()
            if self.api.is_changing(self.klines[-1],
                                    "datetime"):  # 如果产生新k线,则重新计算唐奇安通道及买卖单位
                self.recalc_paramter()
            if self.api.is_changing(self.quote, "last_price"):
                print("最新价: ", self.quote["last_price"])
                if self.quote[
                        "last_price"] > self.donchian_channel_high:  # 当前价>唐奇安通道上轨,买入1个Unit;(持多仓)
                    print("当前价>唐奇安通道上轨,买入1个Unit(持多仓):", self.unit, "手")
                    self.set_position(self.state["position"] + self.unit)
                elif self.quote[
                        "last_price"] < self.donchian_channel_low:  # 当前价<唐奇安通道下轨,卖出1个Unit;(持空仓)
                    print("当前价<唐奇安通道下轨,卖出1个Unit(持空仓):", self.unit, "手")
                    self.set_position(self.state["position"] - self.unit)

    def try_close(self):
        """交易策略"""
        while self.state["position"] != 0:
            self.api.wait_update()
            if self.api.is_changing(self.quote, "last_price"):
                print("最新价: ", self.quote["last_price"])

                if self.state["position"] > 0:  # 持多单
                    # 加仓策略: 如果是多仓且资产的价格在上一次建仓(或者加仓)的基础上又上涨了0.5N,就再加一个Unit的多仓
                    if self.quote["last_price"] >= self.state[
                            "last_price"] + 0.5 * self.n:
                        print("加仓:加1个Unit的多仓")
                        self.set_position(self.state["position"] + self.unit)
                    # 止损策略: 如果是多仓且资产的价格在上一次建仓(或者加仓)的基础上又下跌了2N,就卖出全部头寸止损
                    elif self.quote["last_price"] <= self.state[
                            "last_price"] - 2 * self.n:
                        print("止损:卖出全部头寸")
                        self.set_position(0)
                    # 止盈策略: 如果是多仓且当前资产价格跌破了10日唐奇安通道的下轨,就清空所有头寸结束策略,离场
                    if self.quote["last_price"] <= min(
                            self.klines.
                            low[-self.donchian_channel_stop_profit - 1:-1]):
                        print("止盈:清空所有头寸结束策略,离场")
                        self.set_position(0)

                elif self.state["position"] < 0:  # 持空单
                    # 加仓策略: 如果是空仓且资产的价格在上一次建仓(或者加仓)的基础上又下跌了0.5N,就再加一个Unit的空仓
                    if self.quote["last_price"] <= self.state[
                            "last_price"] - 0.5 * self.n:
                        print("加仓:加1个Unit的空仓")
                        self.set_position(self.state["position"] - self.unit)
                    # 止损策略: 如果是空仓且资产的价格在上一次建仓(或者加仓)的基础上又上涨了2N,就平仓止损
                    elif self.quote["last_price"] >= self.state[
                            "last_price"] + 2 * self.n:
                        print("止损:卖出全部头寸")
                        self.set_position(0)
                    # 止盈策略: 如果是空仓且当前资产价格升破了10日唐奇安通道的上轨,就清空所有头寸结束策略,离场
                    if self.quote["last_price"] >= max(
                            self.klines.
                            high[-self.donchian_channel_stop_profit - 1:-1]):
                        print("止盈:清空所有头寸结束策略,离场")
                        self.set_position(0)

    def strategy(self):
        """海龟策略"""
        print("等待K线及账户数据...")
        deadline = time.time() + 5
        while not self.recalc_paramter():
            if not self.api.wait_update(deadline=deadline):
                raise Exception("获取数据失败,请确认行情连接正常并已经登录交易账户")
        while True:
            self.try_open()
            self.try_close()
示例#2
0
    def test_lib_insert_order_time_check_7(self):
        """
        lib下单时间判断测试7

        订阅合约:
            订阅周六有行情的和周六无行情的
        测试:
            (测试:回测从周六开始时 可交易时间段的计算、判断)
            1 回测刚开始:current_datetime 为 0:00 , 只有cu能下单,另外两个合约直到白盘9点下单
        """
        # 预设服务器端响应
        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.mock.run(
            os.path.join(dir_path, "log_file",
                         "test_lib_insert_order_time_check_7.script.lzma"))

        TqApi.RD = random.Random(4)
        api = TqApi(backtest=TqBacktest(
            datetime.datetime(2019, 11, 30, 0, 0, 0),
            datetime.datetime(2019, 12, 2, 9, 30)),
                    _ins_url=self.ins_url_2019_12_04)
        symbol1 = "SHFE.cu2002"  # 有夜盘,凌晨1点结束夜盘
        symbol2 = "SHFE.rb2002"  # 夜盘23点结束
        symbol3 = "DCE.jd2002"  # 无夜盘
        quote1 = api.get_quote(symbol1)
        quote2 = api.get_quote(symbol2)
        quote3 = api.get_quote(symbol3)
        position1 = api.get_position(symbol1)
        position2 = api.get_position(symbol2)
        position3 = api.get_position(symbol3)
        target_pos1 = TargetPosTask(api, symbol1)
        target_pos2 = TargetPosTask(api, symbol2)
        target_pos3 = TargetPosTask(api, symbol3)
        orders = api.get_order()
        try:
            # 1 回测刚开始:current_datetime 为 0:00 , 只有cu能下单,另外两个合约直到白盘9点下单
            target_pos1.set_target_volume(1)
            target_pos2.set_target_volume(2)
            target_pos3.set_target_volume(3)
            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-11-30 00:02:00.000000":
                api.wait_update()
            self.assertEqual(len(orders), 1)
            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-11-30 00:15:00.000000":
                api.wait_update()
            self.assertEqual(len(orders), 1)
            self.assertEqual(position1.pos, 1)
            self.assertEqual(position2.pos, 0)
            self.assertEqual(position3.pos, 0)

            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-12-02 09:05:00.000000":
                api.wait_update()
            self.assertEqual(len(orders), 3)
            self.assertEqual(position1.pos, 1)
            self.assertEqual(position2.pos, 2)
            self.assertEqual(position3.pos, 3)

            while True:
                api.wait_update()
        except BacktestFinished:
            self.assertEqual(position1.pos, 1)
            self.assertEqual(position2.pos, 2)
            self.assertEqual(position3.pos, 3)
            api.close()
示例#3
0
class Turtle:
    def __init__(self,
                 symbol,
                 account=None,
                 donchian_channel_open_position=20,
                 donchian_channel_stop_profit=10,
                 atr_day_length=20,
                 max_risk_ratio=0.5):
        self.account = account  # 交易账号
        self.symbol = symbol  # 合约代码
        self.donchian_channel_open_position = donchian_channel_open_position  # 唐奇安通道的天数周期(开仓)
        self.donchian_channel_stop_profit = donchian_channel_stop_profit  # 唐奇安通道的天数周期(止盈)
        self.atr_day_length = atr_day_length  # ATR计算所用天数
        self.max_risk_ratio = max_risk_ratio  # 最高风险度
        self.state = {
            "position": 0,  # 本策略净持仓数(正数表示多头,负数表示空头,0表示空仓)
            "last_price": float("nan"),  # 上次调仓价
        }

        self.n = 0  # 平均真实波幅(N值)
        self.unit = 0  # 买卖单位
        self.donchian_channel_high = 0  # 唐奇安通道上轨
        self.donchian_channel_low = 0  # 唐奇安通道下轨

        self.api = TqApi(self.account)
        self.quote = self.api.get_quote(self.symbol)
        # 由于ATR是路径依赖函数,因此使用更长的数据序列进行计算以便使其值稳定下来
        kline_length = max(donchian_channel_open_position + 1,
                           donchian_channel_stop_profit + 1,
                           atr_day_length * 5)
        self.klines = self.api.get_kline_serial(self.symbol,
                                                24 * 60 * 60,
                                                data_length=kline_length)
        self.account = self.api.get_account()
        self.target_pos = TargetPosTask(self.api, self.symbol)

    def recalc_paramter(self):
        # 平均真实波幅(N值)
        self.n = ATR(self.klines, self.atr_day_length)["atr"].iloc[-1]
        # 买卖单位
        self.unit = int((self.account.balance * 0.01) /
                        (self.quote.volume_multiple * self.n))
        # 唐奇安通道上轨:前N个交易日的最高价
        self.donchian_channel_high = max(
            self.klines.high[-self.donchian_channel_open_position - 1:-1])
        # 唐奇安通道下轨:前N个交易日的最低价
        self.donchian_channel_low = min(
            self.klines.low[-self.donchian_channel_open_position - 1:-1])
        print("唐其安通道上下轨: %f, %f" %
              (self.donchian_channel_high, self.donchian_channel_low))
        return True

    def set_position(self, pos):
        self.state["position"] = pos
        self.state["last_price"] = self.quote["last_price"]
        self.target_pos.set_target_volume(self.state["position"])

    def try_open(self):
        """开仓策略"""
        while self.state["position"] == 0:
            self.api.wait_update()
            if self.api.is_changing(self.klines.iloc[-1],
                                    "datetime"):  # 如果产生新k线,则重新计算唐奇安通道及买卖单位
                self.recalc_paramter()
            if self.api.is_changing(self.quote, "last_price"):
                print("最新价: %f" % self.quote.last_price)
                if self.quote.last_price > self.donchian_channel_high:  # 当前价>唐奇安通道上轨,买入1个Unit;(持多仓)
                    print("当前价>唐奇安通道上轨,买入1个Unit(持多仓): %d 手" % self.unit)
                    self.set_position(self.state["position"] + self.unit)
                elif self.quote.last_price < self.donchian_channel_low:  # 当前价<唐奇安通道下轨,卖出1个Unit;(持空仓)
                    print("当前价<唐奇安通道下轨,卖出1个Unit(持空仓): %d 手" % self.unit)
                    self.set_position(self.state["position"] - self.unit)

    def try_close(self):
        """交易策略"""
        while self.state["position"] != 0:
            self.api.wait_update()
            if self.api.is_changing(self.quote, "last_price"):
                print("最新价: ", self.quote.last_price)
                if self.state["position"] > 0:  # 持多单
                    # 加仓策略: 如果是多仓且行情最新价在上一次建仓(或者加仓)的基础上又上涨了0.5N,就再加一个Unit的多仓,并且风险度在设定范围内(以防爆仓)
                    if self.quote.last_price >= self.state[
                            "last_price"] + 0.5 * self.n and self.account.risk_ratio <= self.max_risk_ratio:
                        print("加仓:加1个Unit的多仓")
                        self.set_position(self.state["position"] + self.unit)
                    # 止损策略: 如果是多仓且行情最新价在上一次建仓(或者加仓)的基础上又下跌了2N,就卖出全部头寸止损
                    elif self.quote.last_price <= self.state[
                            "last_price"] - 2 * self.n:
                        print("止损:卖出全部头寸")
                        self.set_position(0)
                    # 止盈策略: 如果是多仓且行情最新价跌破了10日唐奇安通道的下轨,就清空所有头寸结束策略,离场
                    if self.quote.last_price <= min(
                            self.klines.
                            low[-self.donchian_channel_stop_profit - 1:-1]):
                        print("止盈:清空所有头寸结束策略,离场")
                        self.set_position(0)

                elif self.state["position"] < 0:  # 持空单
                    # 加仓策略: 如果是空仓且行情最新价在上一次建仓(或者加仓)的基础上又下跌了0.5N,就再加一个Unit的空仓,并且风险度在设定范围内(以防爆仓)
                    if self.quote.last_price <= self.state[
                            "last_price"] - 0.5 * self.n and self.account.risk_ratio <= self.max_risk_ratio:
                        print("加仓:加1个Unit的空仓")
                        self.set_position(self.state["position"] - self.unit)
                    # 止损策略: 如果是空仓且行情最新价在上一次建仓(或者加仓)的基础上又上涨了2N,就平仓止损
                    elif self.quote.last_price >= self.state[
                            "last_price"] + 2 * self.n:
                        print("止损:卖出全部头寸")
                        self.set_position(0)
                    # 止盈策略: 如果是空仓且行情最新价升破了10日唐奇安通道的上轨,就清空所有头寸结束策略,离场
                    if self.quote.last_price >= max(
                            self.klines.
                            high[-self.donchian_channel_stop_profit - 1:-1]):
                        print("止盈:清空所有头寸结束策略,离场")
                        self.set_position(0)

    def strategy(self):
        """海龟策略"""
        print("等待K线及账户数据...")
        deadline = time.time() + 5
        while not self.recalc_paramter():
            if not self.api.wait_update(deadline=deadline):
                raise Exception("获取数据失败,请确认行情连接正常并已经登录交易账户")
        while True:
            self.try_open()
            self.try_close()
示例#4
0
    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"))
        # 测试: 模拟账户下单
        # 测试脚本重新生成后,数据根据实际情况有变化
        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=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.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': '5c6e433715ba2bdd177219d30e7a269f', 'trade_id': '5c6e433715ba2bdd177219d30e7a269f|1', 'exchange_trade_id': '5c6e433715ba2bdd177219d30e7a269f|1', 'exchange_id': 'DCE', 'instrument_id': 'jd2001', 'direction': 'BUY', 'offset': 'OPEN', 'price': 4087.0, 'volume': 1, 'trade_date_time': 1576121399900001000, 'symbol': 'DCE.jd2001', '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.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': 'cf1822ffbc6887782b491044d5e34124', 'trade_id': 'cf1822ffbc6887782b491044d5e34124|2', 'exchange_trade_id': 'cf1822ffbc6887782b491044d5e34124|2', 'exchange_id': 'SHFE', 'instrument_id': 'cu2001', 'direction': 'BUY', 'offset': 'OPEN', 'price': 49200.0, 'volume': 2, 'trade_date_time': 1576121399900001000, 'symbol': 'SHFE.cu2001', 'user_id': 'TQSIM', 'commission': 23.189999999999998}"
            )

        api.close()
示例#5
0
    def test_lib_insert_order_time_check_4(self):
        '''
        lib下单时间判断测试4

        回测时间:
            起始交易日(datetime.date)为周一
        订阅合约:
            cu(有夜盘,凌晨1点结束夜盘),rb(夜盘23点结束),jd(无夜盘)
        测试:
            (测试周五夜盘21点到周六凌晨1点及周一夜盘、周二白盘)
            1 周五晚21:00之后: cu、rb能下单, jd到周一的9点后下单
            2 周六凌晨1点前:cu能下单
            3 周一早9点后都能下单
            4 周一晚21点后cu、rb能下单
            5 周二白盘开始后,jd能下单
            '''
        # 预设服务器端响应
        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.mock.run(
            os.path.join(dir_path, "log_file",
                         "test_lib_insert_order_time_check_4.script.lzma"))

        TqApi.RD = random.Random(4)
        api = TqApi(backtest=TqBacktest(datetime.date(2019, 12, 2),
                                        datetime.date(2019, 12, 3)),
                    _ins_url=self.ins_url_2019_12_04)  # 2019.12.2:周一
        symbol1 = "SHFE.cu2002"  # 有夜盘,凌晨1点结束夜盘
        symbol2 = "SHFE.rb2002"  # 夜盘23点结束
        symbol3 = "DCE.jd2002"  # 无夜盘
        quote1 = api.get_quote(symbol1)
        quote2 = api.get_quote(symbol2)
        quote3 = api.get_quote(symbol3)
        position1 = api.get_position(symbol1)
        position2 = api.get_position(symbol2)
        position3 = api.get_position(symbol3)
        target_pos1 = TargetPosTask(api, symbol1)
        target_pos2 = TargetPosTask(api, symbol2)
        target_pos3 = TargetPosTask(api, symbol3)
        orders = api.get_order()
        try:
            # 1 周五晚21:00之后: cu、rb能下单, jd到周一的9点后下单
            target_pos1.set_target_volume(1)
            target_pos2.set_target_volume(2)
            target_pos3.set_target_volume(3)
            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-11-29 21:05:00.000000":
                api.wait_update()
            self.assertEqual(len(orders), 2)
            self.assertEqual(position1.pos, 1)
            self.assertEqual(position2.pos, 2)
            self.assertEqual(position3.pos, 0)

            # 2 周五23点后到周六凌晨1点前:cu能下单
            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-11-29 23:00:00.000000":
                api.wait_update()
            target_pos1.set_target_volume(4)
            target_pos2.set_target_volume(5)
            target_pos3.set_target_volume(6)
            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-11-29 23:05:00.000000":
                api.wait_update()
            self.assertEqual(len(orders), 3)
            self.assertEqual(position1.pos, 4)
            self.assertEqual(position2.pos, 2)
            self.assertEqual(position3.pos, 0)

            # 3 周一早9点后都能下单
            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-12-02 09:05:00.000000":
                api.wait_update()
            self.assertEqual(len(orders), 5)
            self.assertEqual(position1.pos, 4)
            self.assertEqual(position2.pos, 5)
            self.assertEqual(position3.pos, 6)

            # 4 周一晚21点后cu、rb能下单
            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-12-02 21:00:00.000000":
                api.wait_update()
            target_pos1.set_target_volume(0)
            target_pos2.set_target_volume(0)
            target_pos3.set_target_volume(0)
            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-12-02 21:15:00.000000":
                api.wait_update()
            self.assertEqual(len(orders), 7)
            self.assertEqual(position1.pos, 0)
            self.assertEqual(position2.pos, 0)
            self.assertEqual(position3.pos, 6)

            # 5 周二白盘开始后,jd能下单
            while max(quote1.datetime, quote2.datetime,
                      quote3.datetime) < "2019-12-03 09:02:00.000000":
                api.wait_update()
            self.assertEqual(len(orders), 8)

            while True:
                api.wait_update()
        except BacktestFinished:
            self.assertEqual(len(orders), 8)
            self.assertEqual(position1.pos, 0)
            self.assertEqual(position2.pos, 0)
            self.assertEqual(position3.pos, 0)
            api.close()
示例#6
0
    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()
示例#7
0
    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()
示例#8
0
    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()
示例#9
0
    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()
示例#10
0
def run_tianqin_code(bid, user_id, pwd, td_url):
    api = TqApi(TqAccount(bid, user_id, pwd), auth="[email protected],MaYanQiong", _stock=True)
    # api = TqApi(TqAccount(bid, user_id, pwd), auth="[email protected],MaYanQiong", _stock=True)
    is_ctp = False if bid == "快期模拟" else True
    account = api.get_account()
    if bid == "快期模拟":
        assert account.ctp_balance == '-' or math.isnan(account.ctp_balance)
        assert account.ctp_available == '-' or math.isnan(account.ctp_available)
    else:
        logger.info(f"{account.ctp_balance}, {account.ctp_available}")

    logger.info(f"{'='*30} 登录成功后,账户初始状态 {'='*30}")
    positions = api._data["trade"][user_id]["positions"]
    orders = api._data["trade"][user_id]["orders"]
    check_orders(orders, api, is_ctp)
    check_positions(positions, api, is_ctp)
    check_account(account, positions, is_ctp)

    logger.info(f"{'='*12} 期权 开仓 {'='*12}")
    quote = api.get_quote("CZCE.CF009C11600")  # ETF 期权
    # 挂单
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price=quote.lower_limit + quote.price_tick, volume=2)
    # 可成交
    order = api.insert_order(symbol="CZCE.CF009C11600", direction="BUY", offset="OPEN", limit_price=quote.ask_price1, volume=1)
    # 可成交 FAK 下单失败,CTP:交易所不支持的价格类型
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price=quote.ask_price1, volume=2, advanced="FAK")
    # 可成交 FOK
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price=quote.ask_price1, volume=2, advanced="FOK")
    # any_price 通知: 下单失败,CTP:交易所不支持的价格类型
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", volume=3)
    # BEST
    # order = api.insert_order(symbol="CFFEX.IF2008", direction="BUY", offset="OPEN", limit_price="BEST", volume=3)
    # BEST FOK 下单失败,已撤单报单被拒绝12038,合约代码:SSE.10002513,下单方向:买,开平标志:开仓,委托价格:最优价,委托手数:3
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price="BEST", volume=3, advanced="FOK")
    # BEST FOK 成交????
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price="BEST", volume=3, advanced="FOK")
    # FIVELEVEL 通知: 下单失败,CTP:交易所不支持的价格类型
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price="FIVELEVEL", volume=3)
    # end = time.time() + 90
    # i = 0
    # while time.time() < end:
    #     i = i + 1
    #     print(i)
    #     order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price="BEST", volume=1)
    #     while order.status == "ALIVE":
    #         api.wait_update()
    api.wait_update()
    api.wait_update()
    api.wait_update()
    api.wait_update()
    api.wait_update()
    check_all(api, bid, user_id)

    # logger.info(f"{'='*30} 发平仓挂单 {'='*30}")
    # positions = api._data["trade"][user_id]["positions"]
    # for pos in positions.values():
    #     symbol = f"{pos.exchange_id}.{pos.instrument_id}"
    #     quote = api.get_quote(symbol)
    #     if pos.pos_long > 0:
    #         api.insert_order(symbol=symbol, direction="SELL", offset="CLOSE",
    #                          limit_price=quote.upper_limit - quote.price_tick,
    #                          volume=pos.pos_long)
    #     if pos.pos_short > 0:
    #         api.insert_order(symbol=symbol, direction="BUY", offset="CLOSE",
    #                          limit_price=quote.lower_limit + quote.price_tick,
    #                          volume=pos.pos_short)
    # check_all(api, bid, user_id)
    api.close()
示例#11
0
文件: tqdata.py 项目: Alan-SH987/vnpy
class TianqinClient:
    """
    Client for querying history data from Tianqin.
    """
    def __init__(self):
        """"""
        self.inited: bool = False
        self.symbols: set = set()
        self.api = None

        self.username: str = SETTINGS["tqdata.username"]
        self.password: str = SETTINGS["tqdata.password"]

    def init(self) -> bool:
        """"""
        if self.inited:
            return True

        if not self.username or not self.password:
            return False

        try:
            self.api = TqApi(auth=TqAuth(self.username, self.password))
            # 获得全部合约
            self.symbols = [k for k, v in self.api._data["quotes"].items()]
        except:
            return False

        self.inited = True
        return True

    def to_tq_symbol(self, symbol: str, exchange: Exchange) -> str:
        """
        TQSdk exchange first
        """
        for count, word in enumerate(symbol):
            if word.isdigit():
                break

        # Check for index symbol
        time_str = symbol[count:]
        if "88" in time_str:
            return f"KQ.m@{exchange.value}.{symbol[:count]}"
        if "99" in time_str:
            return f"KQ.i@{exchange.value}.{symbol[:count]}"

        return f"{exchange.value}.{symbol}"

    def query_history(self, req: HistoryRequest) -> Optional[List[BarData]]:
        """
        Query history bar data from TqSdk.
        """
        symbol = req.symbol
        exchange = req.exchange
        interval = req.interval
        start = req.start
        end = req.end

        tq_symbol = self.to_tq_symbol(symbol, exchange)
        if tq_symbol not in self.symbols:
            return None

        tq_interval = INTERVAL_VT2TQ.get(interval)
        if not tq_interval:
            return None

        # For querying night trading period data
        end += timedelta(1)

        total_num = int((end - start).total_seconds() / tq_interval)
        if total_num > 8964:
            df = self.download_history(start, end, tq_symbol, tq_interval)
        else:
            # 只能用来补充最新的数据,无法指定日期
            df = self.api.get_kline_serial(tq_symbol, tq_interval,
                                           8000).sort_values(by=["datetime"])

            # 时间戳对齐
            df["datetime"] = pd.DatetimeIndex(
                pd.to_datetime(df["datetime"] + TIME_GAP)).tz_localize(
                    'UTC').tz_convert('Asia/Shanghai')

            # 过滤开始结束时间
            df = df[(df['datetime'] >= start - timedelta(days=1))
                    & (df['datetime'] < end)]

        data: List[BarData] = []

        if df is not None:
            for ix, row in df.iterrows():
                bar = BarData(
                    symbol=symbol,
                    exchange=exchange,
                    interval=interval,
                    datetime=row["datetime"].to_pydatetime(),
                    open_price=row["open"],
                    high_price=row["high"],
                    low_price=row["low"],
                    close_price=row["close"],
                    volume=row["volume"],
                    open_interest=row.get("open_oi", 0),
                    gateway_name="TQ",
                )
                data.append(bar)
        return data

    def download_history(self, start, end, symbol, interval):
        """
        下载CSV文件回来,并转换成dataframe
        """
        csv_file = "tqdata.csv"
        status = DataDownloader(api=self.api,
                                symbol_list=[symbol],
                                start_dt=start,
                                end_dt=end,
                                dur_sec=interval,
                                csv_file_name=csv_file)
        while not status.is_finished():
            self.api.wait_update()

        if os.path.exists(csv_file):
            df = pd.read_csv(csv_file)
            df["datetime"] = pd.to_datetime(df["datetime"])

            if interval > 0:
                df = df.rename(columns={f"{symbol}.open": "open"})
                df = df.rename(columns={f"{symbol}.high": "high"})
                df = df.rename(columns={f"{symbol}.low": "low"})
                df = df.rename(columns={f"{symbol}.close": "close"})
                df = df.rename(columns={f"{symbol}.volume": "volume"})
                df = df.rename(columns={f"{symbol}.open_oi": "open_oi"})

            os.unlink(csv_file)
            return df
        else:
            return None
示例#12
0
    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,
                    _td_url=self.td_url,
                    _md_url=self.md_url)  # 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()
示例#13
0
class doubleMA():
    def __init__(self, account, symbol, MA1, MA2, max_value, mini_value,
                 trading_direction, trading_cycle, volume_number):
        self.account = account  #交易账号
        self.symbol = symbol  #合约代码
        self.MA1 = MA1  #小周期
        self.MA2 = MA2  #大周期
        self.max_value = max_value  #震荡区间的最高点
        self.mini_value = mini_value  #震荡区间的最低点
        self.trading_direction = trading_direction  #交易方向 1为涨 0为跌 以下均以 1 0 为定义
        self.trading_cycle = trading_cycle  #交易周期(以分钟记)
        self.volume_number = volume_number  #交易数量
        self.position_flag = 0  #持仓标记
        self.kline_flag = 0  #K线标记 避免单根K线上多次开仓
        self.open_flag = 0  #开仓标记,避免止损点移动

        self.api = TqApi(self.account)
        self.kline = self.api.get_kline_serial(self.symbol,
                                               self.trading_cycle * 60,
                                               data_length=200)
        self.position = self.api.get_position(self.symbol)  #获得持仓状态
        self.sell_list = []
        self.buy_list = []  #存放开仓时的两个k线的最高或者最低点,在开仓时记录平仓时清空

    def open_json(self):
        try:
            fp = open(
                'F:\python\PythonApplication1\PythonApplication1\doubleMA.json',
                'r')
            result = json.load(fp)
            self.buy_list = result['self.buy_list']
            self.sell_list = result['self.sell_list']
            print('buy_list: ', self.buy_list)
            print('sell_list: ', self.sell_list)
        except:
            print("还没有json")

    def save_json(self):
        fp = open(
            'F:\python\PythonApplication1\PythonApplication1\doubleMA.json',
            'w')
        save = {
            'self.buy_list': self.buy_list,
            'self.sell_list': self.sell_list
        }
        json.dump(save, fp)

    def ma(self, daytime):
        close_list = []
        for i in range(1, daytime + 1):
            close_list.append(self.kline[-i]["close"])
        avg = sum(close_list) / daytime
        return avg

    def account_trading(self, trading_direction, offset_flag, td_price):
        if self.position["volume_long"] or self.position["volume_short"] != 0:
            self.position_flag = 1
        if offset_flag == "OPEN":
            if self.position_flag != 1:
                self.api.insert_order(symbol=self.symbol,
                                      direction=trading_direction,
                                      offset=offset_flag,
                                      volume=self.volume_number,
                                      limit_price=td_price)
                self.position_flag = 1
        if offset_flag == "CLOSE":
            if self.position_flag == 1:
                if self.position["volume_long_today"] or self.position[
                        "volume_short_today"] != 0:
                    self.api.insert_order(symbol=self.symbol,
                                          direction=trading_direction,
                                          offset="CLOSETODAY",
                                          volume=self.volume_number,
                                          limit_price=td_price)
                    self.position_flag = 0
                elif self.position["volume_long_his"] or self.position[
                        "volume_short_his"] != 0:
                    self.api.insert_order(symbol=self.symbol,
                                          direction=trading_direction,
                                          offset="CLOSE",
                                          volume=self.volume_number,
                                          limit_price=td_price)
                    self.position_flag = 0

    def close_buy(self):
        if self.position_flag == 1:
            if (self.trading_direction == 1):  #平多
                while True:
                    self.api.wait_update()
                    if (self.kline[-1]["close"] < self.buy_list[-1]):
                        self.account_trading("SELL", "CLOSE",
                                             self.kline[-1]["close"])
                        self.kline_flag += 1
                        self.buy_list.clear()
                        self.save_json()
                        self.open_flag -= 1
                        break
                    if (self.kline[-1]["close"] > self.max_value):
                        break
            if (self.trading_direction == 0):
                while True:
                    self.api.wait_update()
                    if (self.kline[-1]["close"] > self.sell_list[-1]):
                        self.account_trading("BUY", "CLOSE",
                                             self.kline[-1]["close"])
                        self.kline_flag += 1
                        self.open_flag -= 1
                        self.sell_list.clear()
                        self.save_json()
                        break
                    if (self.kline[-1]["close"] < self.mini_value):
                        break

    def open_buy(self):
        if self.position_flag == 0:
            if (self.trading_direction == 1):  #交易方向为涨
                if self.kline_flag == 0:
                    while True:
                        self.api.wait_update()
                        ma1 = self.ma(self.MA1)
                        ma2 = self.ma(self.MA2)
                        if (self.kline[-1]["close"] >=
                                self.kline[-2]["high"]):  #突破最高点开仓
                            self.account_trading("BUY", "OPEN",
                                                 self.kline[-1]["close"])
                            if self.open_flag == 0:
                                self.buy_list.append(int(
                                    self.kline[-1]["low"]))
                                self.buy_list.append(int(
                                    self.kline[-2]["low"]))
                                self.buy_list.sort()
                                self.buy_list.pop()  #抛弃掉最大的
                                self.save_json()
                                self.open_flag += 1
                            self.kline_flag += 1
                            print("止损点:", self.buy_list[-1])
                            break
                        if (self.kline[-1]["close"] <
                                self.mini_value) or (ma1 > ma2):
                            break
            elif (self.trading_direction == 0):  #交易方向为跌
                if self.kline_flag == 0:
                    while True:
                        self.api.wait_update()
                        ma1 = self.ma(self.MA1)
                        ma2 = self.ma(self.MA2)
                        if (self.kline[-1]["close"] <= self.kline[-2]["low"]):
                            self.account_trading("SELL", "OPEN",
                                                 self.kline[-1]["close"])
                            if self.open_flag == 0:
                                self.sell_list.append(
                                    int(self.kline[-1]["high"]))
                                self.sell_list.append(
                                    int(self.kline[-2]["high"]))
                                self.sell_list.sort(reverse=True)
                                self.sell_list.pop()  #抛弃掉最小的
                                self.open_flag += 1
                                self.save_json()
                            self.kline_flag += 1
                            print("止损点:", self.sell_list[-1])
                            break
                        if (self.kline[-1]["close"] > self.max_value) or (ma1 <
                                                                          ma2):
                            break

    def star(self):
        self.open_json()
        if self.position["volume_long"] or self.position["volume_short"] != 0:
            self.position_flag = 1
        while True:
            self.api.wait_update()
            if self.api.is_changing(self.kline[-1], "datetime"):
                self.kline_flag = 0
            #开仓方法
            ma1 = self.ma(self.MA1)
            ma2 = self.ma(self.MA2)
            if self.trading_direction == 1:  #做多
                if self.kline[-1]["close"] > self.mini_value and self.kline[
                        -1]["close"] < self.max_value:
                    if ma2 > ma1:
                        #print('震荡区间中')
                        self.open_buy()
                        self.close_buy()
                elif self.kline[-1]["close"] < self.mini_value:
                    self.close_buy()
                    break
                elif self.kline[-1]["close"] > self.max_value:
                    if ma1 < ma2:
                        self.account_trading("SELL", "CLOSE",
                                             self.kline[-1]["close"])
                        break
                    else:
                        self.open_buy()
                        self.close_buy()
            elif self.trading_direction == 0:  #做空
                if self.kline[-1]["close"] > self.mini_value and self.kline[
                        -1]["close"] < self.max_value:
                    if ma1 > ma2:
                        self.open_buy()
                        self.close_buy()
                elif self.kline[-1]["close"] > self.max_value:
                    self.close_buy()
                    break
                elif self.kline[-1]["close"] < self.mini_value:
                    if ma1 > ma2:
                        self.account_trading("BUY", "CLOSE",
                                             self.kline[-1]["close"])
                        break
                    else:
                        self.open_buy()
                        self.close_buy()
        self.api.close()
示例#14
0
    def test_insert_order_fak(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_fak_simulate.script.lzma"))
        # 测试: 模拟账户下单
        # 非回测, 则需在盘中生成测试脚本: 测试脚本重新生成后,数据根据实际情况有变化,因此需要修改assert语句的内容

        utils.RD = random.Random(2)
        api = TqApi(_ins_url=self.ins_url_2020_05_07,
                    _td_url=self.td_url,
                    _md_url=self.md_url)
        order1 = api.insert_order("SHFE.au2012",
                                  "BUY",
                                  "OPEN",
                                  2,
                                  limit_price=419,
                                  advanced="FAK")
        order2 = api.insert_order("SHFE.cu2010",
                                  "BUY",
                                  "OPEN",
                                  2,
                                  limit_price=49100,
                                  advanced="FAK")
        while order1.status == "ALIVE" or order2.status == "ALIVE":
            api.wait_update()
        self.assertEqual(order1.order_id,
                         "PYSDK_insert_5c6e433715ba2bdd177219d30e7a269f")
        self.assertEqual(order1.direction, "BUY")
        self.assertEqual(order1.offset, "OPEN")
        self.assertEqual(order1.volume_orign, 2)
        self.assertEqual(order1.volume_left, 0)
        self.assertEqual(order1.limit_price, 419.0)  # 判断nan
        self.assertEqual(order1.price_type, "LIMIT")
        self.assertEqual(order1.volume_condition, "ANY")
        self.assertEqual(order1.time_condition, "IOC")
        self.assertAlmostEqual(1593671890008459000 / 1e9,
                               order1.insert_date_time / 1e9,
                               places=1)
        self.assertEqual(order1.status, "FINISHED")
        for k, v in order1.trade_records.items():  # 模拟交易为一次性全部成交,因此只有一条成交记录
            self.assertAlmostEqual(1593671890008850000 / 1e9,
                                   v.trade_date_time / 1e9,
                                   places=1)
            del v.trade_date_time
            self.assertEqual(
                str(v),
                "{'order_id': 'PYSDK_insert_5c6e433715ba2bdd177219d30e7a269f', 'trade_id': 'PYSDK_insert_5c6e433715ba2bdd177219d30e7a269f|2', 'exchange_trade_id': 'PYSDK_insert_5c6e433715ba2bdd177219d30e7a269f|2', 'exchange_id': 'SHFE', 'instrument_id': 'au2012', 'direction': 'BUY', 'offset': 'OPEN', 'price': 419.0, 'volume': 2, 'user_id': 'TQSIM', 'commission': 20.0}"
            )

        self.assertEqual(order2.order_id,
                         "PYSDK_insert_cf1822ffbc6887782b491044d5e34124")
        self.assertEqual(order2.direction, "BUY")
        self.assertEqual(order2.offset, "OPEN")
        self.assertEqual(order2.volume_orign, 2)
        self.assertEqual(order2.volume_left, 2)
        self.assertEqual(order2.limit_price, 49100.0)
        self.assertEqual(order2.price_type, "LIMIT")
        self.assertEqual(order2.volume_condition, "ANY")
        self.assertEqual(order2.time_condition, "IOC")
        self.assertAlmostEqual(1593671890009772000 / 1e9,
                               order2.insert_date_time / 1e9,
                               places=1)
        self.assertEqual(order2.status, "FINISHED")
        self.assertEqual(len(order2.trade_records.items()), 0)  # 没有成交记录
        api.close()
示例#15
0
    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_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()
示例#16
0
    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()
示例#17
0
    def test_insert_order_option(self):
        """
            期权下单
        """
        # 预设服务器端响应
        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.mock.run(
            os.path.join(
                dir_path, "log_file",
                "test_td_basic_insert_order_simulate_option.script.lzma"))
        # 测试: 模拟账户下单
        # 非回测, 则需在盘中生成测试脚本: 测试脚本重新生成后,数据根据实际情况有变化,因此需要修改assert语句的内容
        TqApi.RD = random.Random(2)
        api = TqApi(_ins_url=self.ins_url_2020_04_02,
                    _td_url=self.td_url,
                    _md_url=self.md_url)

        order1 = api.insert_order("SHFE.cu2006C47000",
                                  "BUY",
                                  "OPEN",
                                  1,
                                  limit_price=135)
        order2 = api.insert_order("CZCE.SR007C5600",
                                  "SELL",
                                  "OPEN",
                                  2,
                                  limit_price=30)
        order3 = api.insert_order("DCE.m2007-P-2900",
                                  "BUY",
                                  "OPEN",
                                  3,
                                  limit_price=192)

        while order1.status == "ALIVE" or order2.status == "ALIVE" or order3.status == "ALIVE":
            api.wait_update()

        self.assertEqual(order1.order_id, "5c6e433715ba2bdd177219d30e7a269f")
        self.assertEqual(order1.direction, "BUY")
        self.assertEqual(order1.offset, "OPEN")
        self.assertEqual(order1.volume_orign, 1)
        self.assertEqual(order1.volume_left, 0)
        self.assertEqual(order1.limit_price, 135.0)
        self.assertEqual(order1.price_type, "LIMIT")
        self.assertEqual(order1.volume_condition, "ANY")
        self.assertEqual(order1.time_condition, "GFD")
        self.assertAlmostEqual(1586829882005334000 / 1e9,
                               order1.insert_date_time / 1e9,
                               places=1)
        self.assertEqual(order1.status, "FINISHED")
        for k, v in order1.trade_records.items():  # 模拟交易为一次性全部成交,因此只有一条成交记录
            self.assertAlmostEqual(1586829882005979000 / 1e9,
                                   v.trade_date_time / 1e9,
                                   places=1)
            del v.trade_date_time
            self.assertEqual(
                str(v),
                "{'order_id': '5c6e433715ba2bdd177219d30e7a269f', 'trade_id': '5c6e433715ba2bdd177219d30e7a269f|1', 'exchange_trade_id': '5c6e433715ba2bdd177219d30e7a269f|1', 'exchange_id': 'SHFE', 'instrument_id': 'cu2006C47000', 'direction': 'BUY', 'offset': 'OPEN', 'price': 135.0, 'volume': 1, 'user_id': 'TQSIM', 'commission': 10}"
            )

        self.assertEqual(order2.order_id, "cf1822ffbc6887782b491044d5e34124")
        self.assertEqual(order2.direction, "SELL")
        self.assertEqual(order2.offset, "OPEN")
        self.assertEqual(order2.volume_orign, 2)
        self.assertEqual(order2.volume_left, 0)
        self.assertEqual(order2.limit_price, 30.0)
        self.assertEqual(order2.price_type, "LIMIT")
        self.assertEqual(order2.volume_condition, "ANY")
        self.assertEqual(order2.time_condition, "GFD")
        self.assertAlmostEqual(1586829882236154000 / 1e9,
                               order2.insert_date_time / 1e9,
                               places=1)
        self.assertEqual(order2.status, "FINISHED")
        for k, v in order2.trade_records.items():  # 模拟交易为一次性全部成交,因此只有一条成交记录
            self.assertAlmostEqual(1586829882236518000 / 1e9,
                                   v.trade_date_time / 1e9,
                                   places=1)
            del v.trade_date_time
            self.assertEqual(
                str(v),
                "{'order_id': 'cf1822ffbc6887782b491044d5e34124', 'trade_id': 'cf1822ffbc6887782b491044d5e34124|2', 'exchange_trade_id': 'cf1822ffbc6887782b491044d5e34124|2', 'exchange_id': 'CZCE', 'instrument_id': 'SR007C5600', 'direction': 'SELL', 'offset': 'OPEN', 'price': 30.0, 'volume': 2, 'user_id': 'TQSIM', 'commission': 20}"
            )

        self.assertEqual(order3.order_id, "4067c3584ee207f8da94e3e8ab73738f")
        self.assertEqual(order3.direction, "BUY")
        self.assertEqual(order3.offset, "OPEN")
        self.assertEqual(order3.volume_orign, 3)
        self.assertEqual(order3.volume_left, 0)
        self.assertEqual(order3.limit_price, 192.0)
        self.assertEqual(order3.price_type, "LIMIT")
        self.assertEqual(order3.volume_condition, "ANY")
        self.assertEqual(order3.time_condition, "GFD")
        self.assertAlmostEqual(1586829882228039000 / 1e9,
                               order3.insert_date_time / 1e9,
                               places=1)
        self.assertEqual(order3.status, "FINISHED")
        for k, v in order3.trade_records.items():  # 模拟交易为一次性全部成交,因此只有一条成交记录
            self.assertAlmostEqual(1586829882228603000 / 1e9,
                                   v.trade_date_time / 1e9,
                                   places=1)
            del v.trade_date_time
            self.assertEqual(
                str(v),
                "{'order_id': '4067c3584ee207f8da94e3e8ab73738f', 'trade_id': '4067c3584ee207f8da94e3e8ab73738f|3', 'exchange_trade_id': '4067c3584ee207f8da94e3e8ab73738f|3', 'exchange_id': 'DCE', 'instrument_id': 'm2007-P-2900', 'direction': 'BUY', 'offset': 'OPEN', 'price': 192.0, 'volume': 3, 'user_id': 'TQSIM', 'commission': 30}"
            )

        api.close()
示例#18
0
    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()
示例#19
0
def run_tianqin_code(bid, user_id, pwd, td_url):
    api = TqApi(TqAccount(bid, user_id, pwd),
                auth="[email protected],MaYanQiong",
                _td_url=td_url)
    is_ctp = False if bid == "快期模拟" else True
    account = api.get_account()
    if bid == "快期模拟":
        assert account.ctp_balance == '-' or math.isnan(account.ctp_balance)
        assert account.ctp_available == '-' or math.isnan(
            account.ctp_available)
    else:
        logger.info(f"{account.ctp_balance}, {account.ctp_available}")

    logger.info(f"{'='*30} 登录成功后,账户初始状态 {'='*30}")
    positions = api._data["trade"][user_id]["positions"]
    orders = api._data["trade"][user_id]["orders"]
    check_orders(orders, api, is_ctp)
    check_positions(positions, api, is_ctp)
    check_account(account, positions, is_ctp)

    logger.info(f"{'='*30} 全部撤单 & 全部平仓 {'='*30}")
    for order in orders.values():
        if order.status != "FINISHED":
            api.cancel_order(order)

    for pos in positions.values():
        symbol = f"{pos.exchange_id}.{pos.instrument_id}"
        quote = api.get_quote(symbol)
        if pos.pos_long > 0:
            api.insert_order(symbol=symbol,
                             direction="SELL",
                             offset="CLOSE",
                             limit_price=quote.bid_price1,
                             volume=pos.pos_long)
        if pos.pos_short > 0:
            api.insert_order(symbol=symbol,
                             direction="BUY",
                             offset="CLOSE",
                             limit_price=quote.ask_price1,
                             volume=pos.pos_short)

    while True:
        api.wait_update(deadline=time.time() + 30)
        # 全部持仓清 0
        is_all_clear = True
        for pos in positions.values():
            if pos.pos_long > 0 or pos.pos_short > 0:
                is_all_clear = False
        for order in orders.values():
            if order.status != "FINISHED":
                is_all_clear = False
        if is_all_clear:
            logger.info("全部撤单 & 全部平仓 ok")
            break
        else:
            logger.info("还没完成全部撤单 & 全部平仓")

    logger.info(f"{'='*12} 期货 开仓 {'='*12}")
    quote = api.get_quote("CZCE.RM105")
    api.insert_order(symbol="CZCE.RM105",
                     direction="BUY",
                     offset="OPEN",
                     limit_price=quote.lower_limit + quote.price_tick,
                     volume=2)
    api.insert_order(symbol="CZCE.RM105",
                     direction="BUY",
                     offset="OPEN",
                     limit_price=quote.ask_price1,
                     volume=3)
    quote1 = api.get_quote("CZCE.CF105")
    api.insert_order(symbol="CZCE.CF105",
                     direction="SELL",
                     offset="OPEN",
                     limit_price=quote1.upper_limit - quote1.price_tick,
                     volume=2)
    api.insert_order(symbol="CZCE.CF105",
                     direction="SELL",
                     offset="OPEN",
                     limit_price=quote1.bid_price1,
                     volume=3)
    check_all(api, bid, user_id)

    # logger.info(f"{'='*12} 期权 开仓 {'='*12}")
    # quote = api.get_quote("CZCE.RM009C2300")
    # api.insert_order(symbol="CZCE.RM009C2300", direction="BUY", offset="OPEN",
    #                          limit_price=quote.lower_limit + quote.price_tick,
    #                          volume=2)
    # api.insert_order(symbol="CZCE.RM009C2300", direction="BUY", offset="OPEN", limit_price=quote.ask_price1,
    #                          volume=3)
    # quote1 = api.get_quote("CZCE.CF009C11600")
    # api.insert_order(symbol="CZCE.CF009C11600", direction="SELL", offset="OPEN",
    #                          limit_price=quote1.upper_limit - quote1.price_tick,
    #                          volume=2)
    # api.insert_order(symbol="CZCE.CF009C11600", direction="SELL", offset="OPEN", limit_price=quote1.bid_price1,
    #                          volume=3)
    #
    # quote2 = api.get_quote("CZCE.RM009P2300")
    # api.insert_order(symbol="CZCE.RM009P2300", direction="BUY", offset="OPEN",
    #                  limit_price=quote2.lower_limit + quote2.price_tick,
    #                  volume=2)
    # api.insert_order(symbol="CZCE.RM009P2300", direction="BUY", offset="OPEN", limit_price=quote2.ask_price1,
    #                  volume=3)
    # quote3 = api.get_quote("CZCE.CF009C11600")
    # api.insert_order(symbol="CZCE.CF009P11600", direction="SELL", offset="OPEN",
    #                  limit_price=quote3.upper_limit - quote3.price_tick,
    #                  volume=2)
    # api.insert_order(symbol="CZCE.CF009P11600", direction="SELL", offset="OPEN", limit_price=quote3.bid_price1,
    #                  volume=3)

    # PUT
    # check_all(api, bid, user_id)

    # logger.info(f"{'='*30} 发平仓挂单 {'='*30}")
    # positions = api._data["trade"][user_id]["positions"]
    # for pos in positions.values():
    #     symbol = f"{pos.exchange_id}.{pos.instrument_id}"
    #     quote = api.get_quote(symbol)
    #     if pos.pos_long > 0:
    #         api.insert_order(symbol=symbol, direction="SELL", offset="CLOSE",
    #                          limit_price=quote.upper_limit - quote.price_tick,
    #                          volume=pos.pos_long)
    #     if pos.pos_short > 0:
    #         api.insert_order(symbol=symbol, direction="BUY", offset="CLOSE",
    #                          limit_price=quote.lower_limit + quote.price_tick,
    #                          volume=pos.pos_short)
    # check_all(api, bid, user_id)
    api.close()
示例#20
0
    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()
示例#21
0
    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(
            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', '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': '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', 'insert_date_time': 631123200000000000, 'last_msg': '全部成交', 'status': 'FINISHED', 'user_id': 'TQSIM', 'symbol': 'SHFE.cu2001', 'frozen_margin': 0.0}"
        )

        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.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,
                         "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.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()
示例#22
0
    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()
示例#23
0
    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"))

        TqApi.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()
示例#24
0
    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(
            "PYSDK_insert_1710cf5327ac435a7a97c643656412a9|1")
        trade2 = api.get_trade(
            "PYSDK_insert_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': 'PYSDK_insert_1710cf5327ac435a7a97c643656412a9', 'trade_id': 'PYSDK_insert_1710cf5327ac435a7a97c643656412a9|1', 'exchange_trade_id': 'PYSDK_insert_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': 'PYSDK_insert_8ca5996666ceab360512bd1311072231', 'trade_id': 'PYSDK_insert_8ca5996666ceab360512bd1311072231|2', 'exchange_trade_id': 'PYSDK_insert_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()
示例#25
0
    def test_lib_insert_order_time_check_1(self):
        """
        lib下单时间判断测试1

        回测时间:
            周一21:00 - 周二10:00
        合约订阅:
            无夜盘; 有夜盘24:00结束; 有夜盘25:00结束
        测试:
            21:00起始时刻两个有夜盘合约立即下單,无夜盘合约第二日白盘下单;
            23:00某一夜盘合约停止交易后不能下單,另一合约能下單;
        """
        # 预设服务器端响应
        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.mock.run(
            os.path.join(dir_path, "log_file",
                         "test_lib_insert_order_time_check_1.script.lzma"))

        TqApi.RD = random.Random(4)
        api = TqApi(backtest=TqBacktest(
            datetime.datetime(2019, 12, 2, 21, 0, 0),
            datetime.datetime(2019, 12, 3, 10, 0, 0)),
                    _ins_url=self.ins_url_2019_12_04)  # 2019.12.2周一
        symbol1 = "DCE.jd2002"  # 无夜盘
        symbol2 = "SHFE.rb2002"  # 夜盘23点结束
        symbol3 = "SHFE.cu2002"  # 夜盘凌晨1点结束
        quote3 = api.get_quote(symbol3)
        target_pos1 = TargetPosTask(api, symbol1)
        target_pos2 = TargetPosTask(api, symbol2)
        target_pos3 = TargetPosTask(api, symbol3)
        position1 = api.get_position(symbol1)
        position2 = api.get_position(symbol2)
        position3 = api.get_position(symbol3)
        orders = api.get_order()
        try:
            # 1 21:00起始时刻有夜盘合约立即下單,无夜盘合约第二日白盘下单;
            target_pos1.set_target_volume(1)
            target_pos2.set_target_volume(2)
            target_pos3.set_target_volume(3)
            while datetime.datetime.strptime(
                    quote3.datetime,
                    "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime(
                        2019, 12, 2, 21, 2):
                api.wait_update()
            self.assertEqual(len(orders), 2)
            self.assertEqual(position1.pos, 0)
            self.assertEqual(position2.pos, 2)
            self.assertEqual(position3.pos, 3)

            # 2 23:00某一夜盘合约停止交易后不能下單,另一合约能下單;
            while datetime.datetime.strptime(
                    quote3.datetime,
                    "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime(
                        2019, 12, 3, 0, 0):
                api.wait_update()
            target_pos1.set_target_volume(4)
            target_pos2.set_target_volume(5)
            target_pos3.set_target_volume(6)
            while datetime.datetime.strptime(
                    quote3.datetime,
                    "%Y-%m-%d %H:%M:%S.%f") < datetime.datetime(
                        2019, 12, 3, 0, 30):
                api.wait_update()
            self.assertEqual(len(orders), 3)
            self.assertEqual(position1.pos, 0)
            self.assertEqual(position2.pos, 2)
            self.assertEqual(position3.pos, 6)

            while True:
                api.wait_update()
        except BacktestFinished:
            # 验证下單情況
            # 第二个交易日白盘,将所有合约调整到目标手数
            self.assertEqual(len(orders), 5)
            self.assertEqual(position1.pos, 4)
            self.assertEqual(position2.pos, 5)
            self.assertEqual(position3.pos, 6)
            print("回测结束")
            api.close()
def linear(data1,data2):
    regr = linear_model.LinearRegression()
    data1=np.transpose(np.array(data1)).reshape(1,-1)
    data2=np.transpose(np.array(data2)).reshape(1,-1)
    result=regr.fit(data1,data2)
    alpha = np.mean(result.intercept_)
    beta = np.mean(result.coef_)
    data1_adj = alpha + beta * data2
    residuals = data1_adj - data1
    mean = np.mean(residuals)
    std = np.std(residuals)
    result_all = [mean,std,beta,alpha]    
    return (result_all)

while True:                                                 #判断开仓条件的主循环
    api.wait_update()                                       #等待业务数据更新
    if api.is_changing(klines_b):
        linear_result = linear(klines_a.close_oi,klines_b.close_oi)
        print(linear_result)
        spread = linear_result[3]+linear_result[2]*klines_a['close'].tolist()[-1]-klines_b['close'].tolist()[-1]
        print(spread)
        if spread < linear_result[0]+ 2*linear_result[1]:   #实际调整为2个sigma
            print("此为多头市场")
            target_pos.set_target_volume(50)
        elif spread > linear_result[0]- 2*linear_result[1]:
            print("此为空头市场")
            target_pos.set_target_volume(-50)               #如果触发了,则通过 target_pos 将 目标持仓设置为多头 1 手,具体的调仓工作则由 target_pos 在后台完成
        break                                               #跳出开仓循环,进入下面的平仓循环

while True:                                                 #判断平仓条件的主循环
    api.wait_update()                                       #等待业务数据更新
示例#27
0
symbol = "SHFE.cu1905"  # 合约代码
close_hour, close_minute = 14, 50  # 平仓时间

api = TqApi(TqSim())  # 使用模拟帐号直连行情和交易服务器
quote = api.get_quote(symbol)  # 获取指定合约的盘口行情
klines = api.get_kline_serial(symbol, 24 * 60 * 60)  # 获取日线
position = api.get_position(symbol)  # 持仓信息
target_pos = TargetPosTask(api, symbol)  # 目标持仓

top_rail = klines.high.iloc[-2]  # 上轨: 昨日高点
bottom_rail = klines.low.iloc[-2]  # 下轨: 昨日低点
print("上轨:", top_rail, ",下轨:", bottom_rail, ",昨日收盘价:", klines.close.iloc[-2],
      ",今日开盘价:", klines.open.iloc[-1])

while True:
    api.wait_update()
    if api.is_changing(klines.iloc[-1],
                       "datetime"):  # 如果产生一根新日线 (即到达下一个交易日): 重新获取上下轨
        top_rail = klines.high.iloc[-2]
        bottom_rail = klines.low.iloc[-2]
        print("上轨:", top_rail, ",下轨:", bottom_rail, ",昨日收盘价:",
              klines.close.iloc[-2], ",今日开盘价:", klines.open.iloc[-1])

    if api.is_changing(quote, "last_price"):  # 如果行情最新价发生变化
        print("当前最新价", quote.last_price)
        # 开仓突破
        if quote.last_price > top_rail and position.volume_long == 0:  # 如果价格突破上轨: 买入开仓
            print("最新价:", quote.last_price, ", 价格突破上轨,买入开仓")
            target_pos.set_target_volume(3)  # 设置目标持仓手数,将指定合约调整到目标头寸
        elif quote.last_price < bottom_rail and position.volume_short == 0:  # 如果价格跌破下轨: 卖出开仓
            print("最新价:", quote.last_price, ", 价格跌破下轨, 卖出开仓")
示例#28
0
    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_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()
示例#29
0
symbol = "DCE.jd1905"  # 交易合约代码
history_day_length = 20  # 使用多少天的历史数据用来计算每个时间单元的下单手数
time_slot_start = datetime.time(9, 35)  # 计划交易时段起始时间点
time_slot_end = datetime.time(10, 50)  # 计划交易时段终点时间点

api = TqApi(TqSim())
# 根据 history_day_length 推算出需要订阅的历史数据长度, 需要注意history_day_length与time_cell的比例关系以避免超过订阅限制
klines = api.get_kline_serial(symbol,
                              time_cell,
                              data_length=int(10 * 60 * 60 / time_cell *
                                              history_day_length))
target_pos = TargetPosTask(api, symbol)
position = api.get_position(symbol)  # 持仓信息

while not klines.is_ready():  # 等待数据
    api.wait_update()

df = klines.to_dataframe()  # 将k线数据转为DataFrame


def get_kline_time(kline_datetime):
    """获取k线的时间(不包含日期)"""
    kline_time = datetime.datetime.fromtimestamp(kline_datetime //
                                                 1000000000).time()  # 每根k线的时间
    return kline_time


def get_market_day(kline_datetime):
    """获取k线所对应的交易日"""
    kline_dt = datetime.datetime.fromtimestamp(kline_datetime //
                                               1000000000)  # 每根k线的日期和时间
示例#30
0
    def test_get_position(self):
        """
        获取持仓
        """
        # 预设服务器端响应
        self.mock.run("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()