Ejemplo n.º 1
0
          sBreak)
    return pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak


api = TqApi()
quote = api.get_quote(SYMBOL)
klines = api.get_kline_serial(SYMBOL, 24 * 60 * 60)  # 86400: 使用日线
position = api.get_position(SYMBOL)
target_pos = TargetPosTask(api, SYMBOL)
target_pos_value = position.pos_long - position.pos_short  # 目标净持仓数
open_position_price = position.open_price_long if target_pos_value > 0 else position.open_price_short  # 开仓价
pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak = get_index_line(
    klines)  # 七条标准线

while True:
    target_pos.set_target_volume(target_pos_value)
    api.wait_update()
    if api.is_changing(klines.iloc[-1], "datetime"):  # 产生新k线,则重新计算7条指标线
        pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak = get_index_line(
            klines)
    '''交易规则'''
    if api.is_changing(quote, "last_price"):
        print("最新价: ", quote.last_price)

        # 开仓价与当前行情价之差大于止损点则止损
        if (target_pos_value > 0 and open_position_price - quote.last_price >= STOP_LOSS_PRICE) or\
            (target_pos_value < 0 and quote.last_price - open_position_price >= STOP_LOSS_PRICE):
            target_pos_value = 0  # 平仓

        # 反转:
        if target_pos_value > 0:  # 多头持仓
Ejemplo n.º 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()
Ejemplo n.º 3
0
                wait_price(layer + 1)
                # 从下一档位回退到当前档位后, 设置回当前对应的持仓手数
                target_pos.set_target_volume(grid_volume_long[layer + 1])
            # 如果最新价大于当前档位的价格: 则回退到上一档位
            if quote["last_price"] > grid_prices_long[layer]:
                print("最新价: %f, 回退到: 多头第 %d 档" % (quote["last_price"], layer))
                return
    elif layer < 0 or quote["last_price"] >= grid_prices_short[1]:  # 是空头方向
        layer = -layer  # 转为正数便于计算
        while True:
            api.wait_update()
            # 如果当前档位小于最大档位层次,并且最新价大于等于下一个档位的价格: 则设置为下一档位对应的持仓手数后进入下一档位层次
            if layer < GRID_AMOUNT and quote[
                    "last_price"] >= grid_prices_short[layer + 1]:
                target_pos.set_target_volume(-grid_volume_short[layer + 1])
                print("最新价: %f, 进入: 空头第 %d 档" %
                      (quote["last_price"], layer + 1))
                wait_price(-(layer + 1))
                # 从下一档位回退到当前档位后, 设置回当前对应的持仓手数
                target_pos.set_target_volume(-grid_volume_short[layer + 1])
            # 如果最新价小于当前档位的价格: 则回退到上一档位
            if quote["last_price"] < grid_prices_short[layer]:
                print("最新价: %f, 回退到: 空头第 %d 档" % (quote["last_price"], layer))
                return


while True:
    api.wait_update()
    wait_price(0)  # 从第0层开始进入网格
    target_pos.set_target_volume(0)
Ejemplo n.º 4
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()
Ejemplo n.º 5
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()
Ejemplo n.º 6
0
    while True:
        if flag:
            api.wait_update()
        now_time_ = datetime.datetime.strptime(quote1.datetime,
                                               "%Y-%m-%d %H:%M:%S.%f")

        # print(datetime.datetime.strptime(quote1.datetime, "%Y-%m-%d %H:%M:%S.%f"))
        # 进行做多或者做空操作
        if pd.Timedelta(seconds=-15) < trade_date - now_time_ < pd.Timedelta(
                seconds=15):
            for kind, prob, tmp_close_time in zip(trade_kind, trade_prob,
                                                  close_time):
                target_pos = TargetPosTask(api, kind)
                hold_pos = api.get_position(kind).pos
                if prob > buying_prob:
                    target_pos.set_target_volume(hold_pos + 1)
                    direction.append(1)
                else:
                    target_pos.set_target_volume(hold_pos - 1)
                    direction.append(-1)
                hold_kind.append(kind)
                close_datetime.append(tmp_close_time)
                # set_kind.add(kind)
                print(kind, direction[-1], now_time_)
                api.wait_update()
            flag = True
            trade_kind = []
            trade_prob = []
            # break
        elif now_time_ - trade_date > pd.Timedelta(seconds=15):
            break
Ejemplo n.º 7
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()
Ejemplo n.º 8
0
while True:
    api.wait_update()
    if api.is_changing(klines[-1],
                       "datetime"):  # 如果产生一根新日线 (即到达下一个交易日): 重新获取上下轨
        top_rail = klines[-2]["high"]
        bottom_rail = klines[-2]["low"]
        print("上轨:", top_rail, ",下轨:", bottom_rail, ",昨日收盘价:",
              klines[-2]["close"], ",今日开盘价:", klines[-1]["open"])

    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"], ", 价格跌破下轨, 卖出开仓")
            target_pos.set_target_volume(-3)

        # 平仓止损: 当价格 向上突破上轨 或 向下突破下轨 后, 再次回破当日开盘价
        if (quote["highest"] > top_rail and quote["last_price"] <=
                quote["open"]) or (quote["lowest"] < bottom_rail
                                   and quote["last_price"] >= quote["open"]):
            print("平仓止损")
            target_pos.set_target_volume(0)

    if api.is_changing(quote, "datetime"):
        now_time = datetime.strptime(quote["datetime"],
                                     "%Y-%m-%d %H:%M:%S.%f")  # 获取当前的行情时间
Ejemplo n.º 9
0
__author__ = 'chengzhi'

from tqsdk import TqApi, TqSim, TargetPosTask
'''
价差回归
当近月-远月的价差大于200时做空近月,做多远月
当价差小于150时平仓
'''
api = TqApi(TqSim())
quote_near = api.get_quote("SHFE.rb1910")
quote_deferred = api.get_quote("SHFE.rb2001")
# 创建 rb1910 的目标持仓 task,该 task 负责调整 rb1910 的仓位到指定的目标仓位
target_pos_near = TargetPosTask(api, "SHFE.rb1910")
# 创建 rb2001 的目标持仓 task,该 task 负责调整 rb2001 的仓位到指定的目标仓位
target_pos_deferred = TargetPosTask(api, "SHFE.rb2001")

while True:
    api.wait_update()
    if api.is_changing(quote_near) or api.is_changing(quote_deferred):
        spread = quote_near["last_price"] - quote_deferred["last_price"]
        print("当前价差:", spread)
        if spread > 250:
            print("目标持仓: 空近月,多远月")
            # 设置目标持仓为正数表示多头,负数表示空头,0表示空仓
            target_pos_near.set_target_volume(-1)
            target_pos_deferred.set_target_volume(1)
        elif spread < 200:
            print("目标持仓: 空仓")
            target_pos_near.set_target_volume(0)
            target_pos_deferred.set_target_volume(0)
Ejemplo n.º 10
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()
Ejemplo n.º 11
0
#

now_day = now1.day

while True:
    api.wait_update()
    now1 = datetime.datetime.strptime(quote1.datetime,
                                      "%Y-%m-%d %H:%M:%S.%f")  # 当前quote的时间
    now2 = datetime.datetime.strptime(quote1.datetime,
                                      "%Y-%m-%d %H:%M:%S.%f")  # 当前quote的时间

    if now1.day > now_day + 3:
        flag = cointegration_test(np.array(klines1['close']),
                                  np.array(klines2['close']))
        if not flag:
            target_pos1.set_target_volume(0)
            target_pos2.set_target_volume(0)
            print('协整检验不通过,无法交易')
            continue
        now_day = now1.day
        up, up_limit, up_limit2, down, down_limit, down_limit2 = get_param(
            klines1, klines2)

        print('更新参数')
    if not flag:
        continue

    time1 = time.ctime(klines2.iloc[-1].datetime / (10**9))
    if api.is_changing(klines1):
        diff = klines1['close'].iloc[-1] - klines2['close'].iloc[-1]
        print(diff, klines1['close'].iloc[-1], klines2['close'].iloc[-1])
Ejemplo n.º 12
0
# 计算每个时间单元的成交量预测值
predicted_volume = {}  # 记录每个时间单元需调整的持仓量
percentage_left = 1  # 剩余比例
volume_left = target_volume  # 剩余手数
for index, value in predicted_percent.items():
    volume = round(volume_left * (value / percentage_left))
    predicted_volume[index] = volume
    percentage_left -= value
    volume_left -= volume
print("\n各时间单元应下单手数:\n", predicted_volume)

# 交易
current_volume = 0  # 记录已调整持仓量
while True:
    api.wait_update()
    # 新产生一根K线并且在计划交易时间段内: 调整目标持仓量
    if api.is_changing(klines[-1], "datetime"):
        t = datetime.datetime.fromtimestamp(klines[-1]["datetime"] //
                                            1000000000).time()
        if t in predicted_volume:
            current_volume += predicted_volume[t]
            print("到达下一时间单元,调整持仓为:", current_volume)
            target_pos.set_target_volume(current_volume)
    # 用持仓信息判断是否完成所有目标交易手数
    if api.is_changing(position, "volume_long") or api.is_changing(
            position, "volume_short"):
        if position["volume_long"] - position["volume_short"] == target_volume:
            break

api.close()
Ejemplo n.º 13
0
    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()                                       #等待业务数据更新
    if api.is_changing(klines_b):
        linear_result = linear(klines_a.close_oi,klines_b.close_oi)
        spread = linear_result[3]+linear_result[2]*klines_a['close'].tolist()[-1]-klines_b['close'].tolist()[-1]
        if (spread > linear_result[0]+ 7.5*linear_result[1]) or (spread < linear_result[0]< 7.5*linear_result[1]):
            print("止盈")
            target_pos.set_target_volume(0)
        elif (spread < linear_result[0]+4*linear_result[1]) or (spread > linear_result[0]+4*linear_result[1]):
            print("止损")
Ejemplo n.º 14
0
    if api.is_changing(quote):
        '''
        开仓逻辑:
        给定多空趋势
        破boll 指标
        空仓时候开仓
        '''

        if long_short_judgment == 'long':
            # 多头时候boll down 开多
            if quote.last_price < boll_bot:
                #判断没有仓位
                if position.pos_long is None or position.pos_long == 0:
                    order_num = get_order_num(account)
                    target_pos.set_target_volume(order_num)
                    break_long = False
                    print("开多open long: ", quote.datetime, quote.last_price)

        if long_short_judgment == 'short':
            if quote.last_price > boll_up:
                if position.pos_short is None or position.pos_short == 0:
                    order_num = get_order_num(account)
                    target_pos.set_target_volume(-order_num)
                    break_short = False
                    print("open short: ", quote.datetime, quote.last_price)
        '''
        止损, 止盈
        '''
        if position.pos_long is not None:
            if position.pos_long > 0:
Ejemplo n.º 15
0
                    now = datetime.datetime.strptime(quote.datetime, "%Y-%m-%d %H:%M:%S.%f")  # 当前quote的时间
                    # 判断是否到达预定收盘时间: 如果到达 则认为本交易日收盘, 此时预测下一交易日的涨跌情况, 并调整为对应仓位
                    if now.hour == close_hour and now.minute >= close_minute:
                        # 1- 获取数据
                        x_train, y_train, x_predict = get_prediction_data(klines, 75)  # 参数1: K线, 参数2:需要的数据长度

                        # 2- 利用机器学习算法预测下一个交易日的涨跌情况
                        # n_estimators 参数: 选择森林里(决策)树的数目; bootstrap 参数: 选择建立决策树时,是否使用有放回抽样
                        clf = RandomForestClassifier(n_estimators=30, bootstrap=True)
                        clf.fit(x_train, y_train)  # 传入训练数据, 进行参数训练
                        predictions.append(bool(clf.predict([x_predict])))  # 传入测试数据进行预测, 得到预测的结果

                        # 3- 进行交易
                        if predictions[-1] == True:  # 如果预测结果为涨: 买入
                            print(quote.datetime, "预测下一交易日为 涨")
                            target_pos.set_target_volume(10)
                        else:  # 如果预测结果为跌: 卖出
                            print(quote.datetime, "预测下一交易日为 跌")
                            target_pos.set_target_volume(-10)
                        break

    except BacktestFinished:  # 回测结束, 获取预测结果,统计正确率
        klines["pre_close"] = klines["close"].shift(1)  # 增加 pre_close(上一交易日的收盘价) 字段
        klines = klines[-len(predictions) + 1:]  # 取出在回测日期内的K线数据
        klines["prediction"] = predictions[:-1]  # 增加预测的本交易日涨跌情况字段(向后移一个数据目的: 将 本交易日对应下一交易日的涨跌 调整为 本交易日对应本交易日的涨跌)
        results = (klines["close"] - klines["pre_close"] >= 0) == klines["prediction"]

        print(klines)
        print("----回测结束----")
        print("预测结果正误:\n", results)
        print("预测结果数目统计: 总计", len(results),"个预测结果")
Ejemplo n.º 16
0
SYMBOL = "SHFE.bu2006"  # 合约代码

api = TqApi()
print("策略开始运行")

data_length = LONG + 2  # k线数据长度
# "duration_seconds=60"为一分钟线, 日线的duration_seconds参数为: 24*60*60
klines = api.get_kline_serial(SYMBOL,
                              duration_seconds=60,
                              data_length=data_length)
target_pos = TargetPosTask(api, SYMBOL)
print(klines)

while True:
    api.wait_update()

    if api.is_changing(klines.iloc[-1], "datetime"):  # 产生新k线:重新计算SMA
        short_avg = ma(klines["close"], SHORT)  # 短周期
        long_avg = ma(klines["close"], LONG)  # 长周期

        # 均线下穿,做空
        if long_avg.iloc[-2] < short_avg.iloc[-2] and long_avg.iloc[
                -1] > short_avg.iloc[-1]:
            target_pos.set_target_volume(-3)
            print("均线下穿,做空")

        # 均线上穿,做多
        if short_avg.iloc[-2] < long_avg.iloc[-2] and short_avg.iloc[
                -1] > long_avg.iloc[-1]:
            target_pos.set_target_volume(3)
            print("均线上穿,做多")
Ejemplo n.º 17
0
    LL = min(klines.low[-Nday - 1:-1])  # N日最低价的最低价
    range = max(HH - LC, HC - LL)
    buy_line = current_open + range * K1  # 上轨
    sell_line = current_open - range * K2  # 下轨

    print("当前开盘价:", current_open, "\n上轨:", buy_line, "\n下轨:", sell_line)
    return buy_line, sell_line


api = TqApi(TqSim())
quote = api.get_quote(symbol)
klines = api.get_kline_serial(symbol, 24*60*60)  # 86400使用日线
target_pos = TargetPosTask(api, symbol)
buy_line, sell_line = dual_thrust(quote, klines)  # 获取上下轨

while True:
    api.wait_update()
    if api.is_changing(klines[-1], "datetime") or api.is_changing(quote, "open"):  # 新产生一根日线或开盘价发生变化: 重新计算上下轨
        buy_line, sell_line = dual_thrust(quote, klines)

    if api.is_changing(quote, "last_price"):
        print("最新价变化", quote["last_price"], end=':')
        if quote["last_price"] > buy_line:  # 高于上轨
            print("高于上轨,目标持仓 多头3手")
            target_pos.set_target_volume(3)  # 交易
        elif quote["last_price"] < sell_line:  # 低于下轨
            print("低于下轨,目标持仓 空头3手")
            target_pos.set_target_volume(-3)  # 交易
        else:
            print('未穿越上下轨,不调整持仓')
Ejemplo n.º 18
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()
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()
Ejemplo n.º 20
0
            rr=eval('stg.'+tt+'position,account)')
            #give all strategy data,postion and account
            #then strategy have all freedom to make every kind of strategy
            for j in range(1,len(i)):   #one strategy may have more then one target position
                for k in range(len(target_position)):
                    if i[0]==target_position.iloc[k,0] and i[j]==target_position.iloc[k,1]:
                        target_position.iloc[k,2]=int(rr[-1,j-1])  #rr[:,-1] is time                
        #executer.set_target()
        logging.info('target_position:')
        logging.info(target_position)
        logging.info(time.ctime())
#--------------------------------------temp_executer

        for key in range(len(target_position)):
            if time.time()-when>5 and position['SHFE.rb2001'].volume_long-position['SHFE.rb2001'].volume_short != target_position.iloc[0,2]:
                #print('set position')
                when=time.time()
                pos_SHFErb2001.set_target_volume(int(target_position.iloc[0,2]))
                #target_position[key]=0
        #print(time.ctime())
        logging.info('account position is: ')
        logging.info(str(position['SHFE.rb2001'].volume_long-position['SHFE.rb2001'].volume_short))
        logging.info('-----------------------------------')
#---------------------------------------end-------
    if now.tm_hour==15 or now.tm_hour==23 or contral=='q':
        target_position.to_csv('target_position.csv',index=False)  #store target postion to file
        logging.info('stop running!')
        break
#get_input.join()
api.close()