Ejemplo n.º 1
0
def run_tianqin_code(bid, user_id, pwd, td_url):
    api = TqApi(TqAccount(bid, user_id, pwd),
                auth="[email protected],MaYanQiong",
                _stock=True,
                _td_url=td_url,
                debug="c.log")
    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)
    check_risk_rule(api, None)
    check_risk_data(api, "SSE.10002504")

    api.set_risk_management_rule("SZSE", True)

    logger.info(f"{'='*12} 期权 开仓 {'='*12}")
    # quote = api.get_quote("SZSE.91000999")  # ETF 期权  SSE.10002504
    # print(quote)
    # 挂单
    # order = api.insert_order(symbol="SSE.10002504", direction="BUY", offset="OPEN", limit_price=quote.lower_limit + quote.price_tick, volume=2)
    # order = api.insert_order(symbol="SSE.10002504", direction="SELL", offset="OPEN", limit_price=quote.upper_limit - quote.price_tick, volume=2)
    # 可成交
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price=quote.ask_price1, volume=3)
    # 可成交 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")

    # BEST
    order = api.insert_order(symbol="SZSE.91000999",
                             direction="BUY",
                             offset="OPEN",
                             limit_price="BEST",
                             volume=5)
    # BEST FOK 下单失败,已撤单报单被拒绝12038,合约代码:SSE.10002513,下单方向:买,开平标志:开仓,委托价格:最优价,委托手数:3
    # order = api.insert_order(symbol="SSE.10002513", direction="SELL", offset="CLOSE", limit_price="BEST", volume=3, advanced="FOK")

    # any_price 通知: 下单失败,CTP:交易所不支持的价格类型
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", volume=3)
    # FIVELEVEL 通知: 下单失败,CTP:交易所不支持的价格类型
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price="FIVELEVEL", volume=3)
    api.wait_update()
    # api.cancel_order(order)
    while order.status == "ALIVE":
        api.wait_update()
    check_all(api, bid, user_id)
    # check_risk_rule(api,None)
    check_risk_data(api, "SZSE.91000999")
    api.close()
Ejemplo n.º 2
0
    def test_get_account(self):
        """
        获取账户资金信息
        """
        # 预设服务器端响应
        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.mock.run(
            os.path.join(dir_path, "log_file",
                         "test_td_basic_get_account_simulate.script.lzma"))
        # 测试: 获取数据
        api = TqApi(_ins_url=self.ins_url,
                    _td_url=self.td_url,
                    _md_url=self.md_url)
        TqApi.RD = random.Random(4)
        order = api.insert_order("DCE.jd2001",
                                 "BUY",
                                 "OPEN",
                                 1,
                                 limit_price=4570)
        while order.status == "ALIVE":
            api.wait_update()
        account = api.get_account()

        # 测试脚本重新生成后,数据根据实际情况有变化
        self.assertEqual(
            str(account),
            "{'currency': 'CNY', 'pre_balance': 10000000.0, 'static_balance': 10000000.0, 'balance': 9994873.877, 'available': 9992016.477, 'float_profit': -5120.0, 'position_profit': -5120.0, 'close_profit': 0.0, 'frozen_margin': 0.0, 'margin': 2857.4, 'frozen_commission': 0.0, 'commission': 6.122999999999999, 'frozen_premium': 0.0, 'premium': 0.0, 'deposit': 0.0, 'withdraw': 0.0, 'risk_ratio': 0.00028588654896140217}"
        )
        self.assertEqual(account.currency, "CNY")
        self.assertEqual(account.pre_balance, 10000000.0)
        self.assertEqual(9994873.877, account.balance)
        self.assertEqual(6.122999999999999, account["commission"])
        self.assertEqual(2857.4, account["margin"])
        self.assertEqual(-5120.0, account.position_profit)
        api.close()
Ejemplo n.º 3
0
    def test_get_account(self):
        """
        获取账户资金信息
        """
        # 预设服务器端响应
        self.mock.run("test_td_basic_get_account_simulate.script")
        # 测试: 获取数据
        api = TqApi(_ins_url=self.ins_url,
                    _td_url=self.td_url,
                    _md_url=self.md_url)
        TqApi.RD = random.Random(4)
        order = api.insert_order("DCE.jd2001",
                                 "BUY",
                                 "OPEN",
                                 1,
                                 limit_price=4570)
        while order.status == "ALIVE":
            api.wait_update()
        account = api.get_account()

        self.assertEqual(
            str(account),
            "{'currency': 'CNY', 'pre_balance': 10000000.0, 'static_balance': 10000000.0, 'balance': 9999973.877, 'available': 9997116.477, 'float_profit': -20.0, 'position_profit': -20.0, 'close_profit': 0.0, 'frozen_margin': 0.0, 'margin': 2857.4, 'frozen_commission': 0.0, 'commission': 6.122999999999999, 'frozen_premium': 0.0, 'premium': 0.0, 'deposit': 0.0, 'withdraw': 0.0, 'risk_ratio': 0.00028574074644055193}"
        )
        self.assertEqual(account.currency, "CNY")
        self.assertEqual(account.pre_balance, 10000000.0)
        self.assertEqual(9999973.877, account.balance)
        self.assertEqual(6.122999999999999, account["commission"])
        self.assertEqual(2857.4, account["margin"])
        self.assertEqual(-20.0, account.position_profit)
        api.close()
Ejemplo n.º 4
0
    def test_get_account_option(self):
        """
            获取账户资金信息
        """
        # 预设服务器端响应
        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.mock.run(
            os.path.join(
                dir_path, "log_file",
                "test_td_basic_get_account_simulate_option.script.lzma"))
        # 测试: 获取数据
        api = TqApi(_ins_url=self.ins_url_2020_04_02,
                    _td_url=self.td_url,
                    _md_url=self.md_url)
        utils.RD = random.Random(4)

        order1 = api.insert_order("CZCE.SR007C5600",
                                  "SELL",
                                  "OPEN",
                                  2,
                                  limit_price=50)
        order2 = api.insert_order("DCE.m2007-P-2900",
                                  "BUY",
                                  "OPEN",
                                  3,
                                  limit_price=180)

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

        account = api.get_account()

        # 测试脚本重新生成后,数据根据实际情况有变化
        self.assertEqual(
            str(account),
            "{'currency': 'CNY', 'pre_balance': 10000000.0, 'static_balance': 10000000.0, 'balance': 9998650.0, 'available': 9989752.8, 'ctp_balance': nan, 'ctp_available': nan, 'float_profit': -300.0, 'position_profit': 0.0, 'close_profit': 0.0, 'frozen_margin': 0.0, 'margin': 4797.200000000001, 'frozen_commission': 0.0, 'commission': 50.0, 'frozen_premium': 0.0, 'premium': -5400.0, 'deposit': 0.0, 'withdraw': 0.0, 'risk_ratio': 0.00047978477094407754, 'market_value': 4100.0}"
        )
        self.assertEqual(account.currency, "CNY")
        self.assertEqual(account.pre_balance, 10000000.0)
        self.assertEqual(account.balance, 9998650.0)
        self.assertEqual(account["commission"], 50.0)
        self.assertEqual(account["margin"], 4797.200000000001)
        self.assertEqual(account.position_profit, 0.0)
        self.assertEqual(account.available, 9989752.8)
        self.assertNotEqual(account.ctp_balance, account.ctp_balance)  # nan
        self.assertEqual(account.float_profit, -300.0)
        self.assertEqual(account.position_profit, 0.0)
        self.assertEqual(account.margin, 4797.200000000001)
        self.assertEqual(account.commission, 50.0)
        self.assertEqual(account.premium, -5400.0)
        self.assertEqual(account.risk_ratio, 0.00047978477094407754)
        self.assertEqual(account.market_value, 4100.0)
        api.close()
Ejemplo n.º 5
0
from tqsdk import TqApi, TqAccount
import nest_asyncio
nest_asyncio.apply()
# api = TqApi(TqAccount("H华安期货", "117889998", "262010",front_broker='6020',front_url='tcp://183.11.217.235:41207'),web_gui="0.0.0.0:9876")
# api = TqApi(TqAccount("快期模拟", "cjj208", "Chenjj1230"))
api = TqApi(TqAccount("simnow",
                      "090828",
                      "jimc1230",
                      front_broker='9999',
                      front_url='tcp://180.168.146.187:10100'),
            web_gui="0.0.0.0:9876")

# 获得 m2005 的持仓引用,当持仓有变化时 position 中的字段会对应更新
position = api.get_position("SHFE.rb2005")
# 获得资金账户引用,当账户有变化时 account 中的字段会对应更新
account = api.get_account()
# 下单并返回委托单的引用,当该委托单有变化时 order 中的字段会对应更新
order = api.insert_order(symbol="SHFE.rb2005",
                         direction="BUY",
                         offset="OPEN",
                         volume=2,
                         limit_price=3521)
#canorder = api.cancel_order(order)

while True:
    api.wait_update()
    if api.is_changing(order, ["status", "volume_orign", "volume_left"]):
        #subprocess.call("cls",shell=True)
        print("单状态: %s, 已成交: %d 手" %
              (order.status, order.volume_orign - order.volume_left))
    if api.is_changing(position, "pos_long_today"):
Ejemplo n.º 6
0
class Turtle:
    def __init__(self,
                 account,
                 symbol,
                 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,
                                        init_pos=self.state["position"])

    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.º 7
0
data_length = 200  # k线数据长度

SYMBOL = "SHFE.rb2005"  # 合约代码
api = TqApi(TqAccount("simnow", "090828", "jimc1230",front_broker='9999',front_url='tcp://180.168.146.187:10100'),web_gui="0.0.0.0:9876")#web_gui="0.0.0.0:9876"
# api = TqApi(backtest=TqBacktest(start_dt=date(2020, 3,10), end_dt=date(2020, 3, 19)),web_gui="0.0.0.0:9876")#"0.0.0.0:9876"#回测模式
# api = TqApi(backtest = TqReplay(date(2020,3,18)),web_gui="0.0.0.0:9876")#复盘模式
print("策略开始运行")


# "duration_seconds=60"为一分钟线, 日线的duration_seconds参数为: 24*60*60
klines = api.get_kline_serial(SYMBOL, duration_seconds=1*60, data_length=data_length)

#收盘后不可查
target_pos = TargetPosTask(api, SYMBOL)
position = api.get_position(SYMBOL)#指定一个品种查看持仓相关信息
account = api.get_account()#获取用户账户资金信息

while True:
    api.wait_update()
    
    

    if api.is_changing(klines.iloc[-1], "datetime"):  # 产生新k线:重新计算SMA
        klines["ma5"]=ma(klines["close"], 5) 
        klines["ma10"]=ma(klines["close"], 10)  
        klines["ma89"]=ma(klines["close"], 89)
        klines["ma144"]=ma(klines["close"], 144)
        sar=SAR(klines, 4, 0.02, 0.2)
        if api.is_changing(klines.iloc[-1], "datetime"):  # 产生新k线:重新计算SMA

            if klines['close'].iloc[-1] < klines['ma89'].iloc[-2]:
def run_tianqin_code(bid, user_id, pwd, td_url):
    api = TqApi(TqAccount(bid, user_id, pwd), auth="[email protected],MaYanQiong", _stock=True,
                _md_url="wss://nfmd.shinnytech.com/t/nfmd/front/mobile", _td_url=td_url)
    print(api._md_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"{'='*12} 期权 开仓 {'='*12}")
    quote = api.get_quote("CZCE.RM105")  # ETF 期权
    print(quote)
    # 挂单
    # 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.RM105", direction="BUY", offset="OPEN", limit_price=quote.ask_price1, volume=1)
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price=quote.ask_price1, volume=3)
    # 可成交 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")

    # BEST
    # order = api.insert_order(symbol="SSE.10002513", direction="SELL", offset="CLOSE", limit_price="BEST", volume=10)
    # BEST FOK 下单失败,已撤单报单被拒绝12038,合约代码:SSE.10002513,下单方向:买,开平标志:开仓,委托价格:最优价,委托手数:3
    # order = api.insert_order(symbol="SSE.10002513", direction="SELL", offset="CLOSE", limit_price="BEST", volume=3, advanced="FOK")

    # any_price 通知: 下单失败,CTP:交易所不支持的价格类型
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", volume=3)
    # FIVELEVEL 通知: 下单失败,CTP:交易所不支持的价格类型
    # order = api.insert_order(symbol="SSE.10002513", direction="BUY", offset="OPEN", limit_price="FIVELEVEL", volume=3)

    while order.status == "ALIVE":
        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()
def double_moving_average(api: TqApi,
                          symbol: str,
                          max_position: int = 10,
                          fast: int = 5,
                          slow: int = 20):
    strategy_name: str = 'DoubleMovingAverage'

    api: TqApi = api
    symbol: str = symbol

    timeout: int = 5

    max_position: int = max_position
    fast: int = fast
    slow: int = slow

    ma: DataFrame = DataFrame()

    tq_account: Account = api.get_account()
    tq_position: Position = api.get_position(symbol)
    tq_candlestick: DataFrame = api.get_kline_serial(symbol=symbol,
                                                     duration_seconds=24 * 60 *
                                                     60)
    tq_target_pos = TargetPosTask(api, symbol)

    deadline: float

    try:
        while True:
            deadline = time.time() + timeout
            if not api.wait_update(deadline=deadline):
                raise RuntimeError('没有在规定时间内获得数据!')
            # api.wait_update()

            if api.is_changing(tq_candlestick):
                ma['fast'] = tafunc.ma(tq_candlestick.close, fast)
                ma['slow'] = tafunc.ma(tq_candlestick.close, slow)

                tq_candlestick['ma_fast'] = ma['fast']
                tq_candlestick['ma_fast.color'] = 'green'
                tq_candlestick['ma_slow'] = ma['slow']
                tq_candlestick['ma_slow.color'] = 0xFF9933CC

                # 最新的快均线数值 > 最新的慢均线数值,且 前一根快均线数值 < 前一根慢均线数值
                # 即快均线从下向上穿过慢均线
                if (ma['fast'].iloc[-1] > ma['slow'].iloc[-1]
                        and ma['fast'].iloc[-2] < ma['slow'].iloc[-2]):
                    # # 如果有空仓,平空仓
                    # if tq_position.pos_short > 0:
                    #     api.insert_order(symbol=symbol,
                    #                           direction='BUY',
                    #                           offset='CLOSE',
                    #                           limit_price=tq_candlestick.close.iloc[-1],
                    #                           volume=tq_position.pos_short
                    #                           )
                    # # 开多仓
                    # api.insert_order(symbol=symbol,
                    #                       direction='BUY',
                    #                       offset='OPEN',
                    #                       limit_price=tq_candlestick.close.iloc[-1],
                    #                       volume=max_position
                    #                       )
                    tq_target_pos.set_target_volume(max_position)

                # 最新的快均线数值 < 最新的慢均线数值,且 前一根快均线数值 > 前一根慢均线数值
                # 即快均线从上向下穿过慢均线
                if (ma['fast'].iloc[-1] < ma['slow'].iloc[-1]
                        and ma['fast'].iloc[-2] > ma['slow'].iloc[-2]):
                    # # 如果有多仓,平多仓
                    # if tq_position.pos_short > 0:
                    #     api.insert_order(symbol=symbol,
                    #                           direction='SELL',
                    #                           offset='CLOSE',
                    #                           limit_price=tq_candlestick.close.iloc[-1],
                    #                           volume=tq_position.pos_short
                    #                           )
                    # # 开空仓
                    # api.insert_order(symbol=symbol,
                    #                       direction='SELL',
                    #                       offset='OPEN',
                    #                       limit_price=tq_candlestick.close.iloc[-1],
                    #                       volume=max_position
                    #                       )
                    tq_target_pos.set_target_volume(-max_position)
    except BacktestFinished:
        api.close()
        print(f'参数: fast={fast}, slow={slow}, 最终权益={tq_account["balance"]}')
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
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()
Ejemplo n.º 12
0
import logging
logging.basicConfig(filename='log.txt',filemode='a',level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#pdb.set_trace()
print('This is yhlz\'s trading server,now started!\n')
try:
    #api=TqApi(TqAccount('快期模拟','284837','86888196'))
    api=TqApi(TqAccount('simnow','133492','Yhlz0000'))
    logging.info('success sign in! with simnow')
    # api=TqApi(TqAccount('H华安期货','100909186','Yhlz0000'))
    # logging.info('success sign in! with 100909186')
except Exception:
    logging.info('problem with sign in!')
    raise SystemExit
contral=''		#use for contral the whole program stop or not ,if it equal to 'q' then progam stoped
account=api.get_account()   #account is a value is a object can used as account.balence etc.
position=api.get_position() #position is a dict where the key is contract,value is each contract's features 
class Get_Input(threading.Thread):		# this thread contral wheather to stop whole program
    def run(self):
        global contral
        while True:
            contral=input('press q to quit!')
            logging.info(contral)
            logging.info(time.ctime())
            now=time.localtime(time.time())
            if now.tm_hour==15 or now.tm_hour==3 or contral=='q':
                logging.info('Ready to quit')
                return 
#######---------------------------get all data and all strategy needed ready-------------------------------------#######
f=open(r'strategytorun.txt')
strategy_list=f.readlines() #a list of strategy need to run