编写天勤策略程序

天勤策略程序是一个标准的Python程序, 使用tqsdk包来实现期货交易功能.

获取实时行情数据

通过 TqSdk 获取实时行情数据是很容易的.

首先, 必须引入 tqsdk 模块:

from tqsdk import TqApi

创建API实例:

api = TqApi()

获得上期所 cu1812 合约的行情引用:

quote = api.get_quote("SHFE.cu1812")

我们可以通过 quote 的各个 key 获得相应的行情字段:

print (quote["datetime"], quote["last_price"])

上面这个例子的完整程序请见 t10.py

处理数据更新

要跟踪行情的变化, 可以使用 wait_update 函数, 如下所示:

quote = api.get_quote("SHFE.cu1812")
# 现在, 我们获得了一个对象 quote. 这个对象总是指向 SHFE.cu1812 合约的最新行情.
print (quote["datetime"], quote["last_price"])

while True:
    api.wait_update()
    print (quote["datetime"], quote["last_price"])

api.wait_update() 是一个阻塞函数, 程序在这行上等待, 直到收到数据包才返回.

上面这个例子的完整程序请见 t20.py

很简单, 对吗? 到这里, 你已经了解用 TqSdk 开发程序的几个关键点:

  • 创建 TqApi 实例
  • 用 api.get_quote() 或 其它函数获取数据引用对象
  • 通过引用对象获得所需数据
  • 在循环中用 api.wait_update() 等待数据包

下面我们将继续介绍 TqSdk 更多的功能. 无论使用哪个功能函数, 都遵循上面的结构.

使用K线数据

你很可能会需要合约的K线数据. 在TqSdk中, 你可以很方便的获得K线数据. 我们来请求 cu1812 合约的10秒线:

klines = api.get_kline_serial("SHFE.cu1812", 10)

跟 api.get_quote() 一样, api.get_kline_serial() 也是返回K线序列的引用对象. K线序列数据也会跟实时行情一起同步自动更新. 你也同样需要用 api.wait_update() 等待数据刷新.

一旦k线数据收到, 你可以通过 klines 访问 k线数据:

print("最后一根K线收盘价", klines.close.iloc[-1])

这部分的完整示例程序请见 t30.py

到这里为止, 你已经知道了如何获取实时行情和K线数据, 下一部分将介绍如何使用你的交易账户并发送交易指令

交易账户, 下单, 撤单

要获得你的账户资金情况, 可以请求一个资金账户引用对象:

account = api.get_account()

要获得你交易账户中某个合约的持仓情况, 可以请求一个持仓引用对象:

position = api.get_position("DCE.m1901")

与行情数据一样, 它们也通过 api.wait_update() 获得更新, 你也同样可以访问它们的成员变量:

print("可用资金: %.2f" % (account["available"]))
print("今多头: %d 手" % (position["volume_long_today"]))

要在交易账户中发出一个委托单, 使用 api.insert_order() 函数:

order = api.insert_order(symbol="DCE.m1901", direction="BUY", offset="OPEN", volume=5)

这个函数调用后会立即返回, order 是一个指向此委托单的引用对象, 你总是可以通过它的成员变量来了解委托单的最新状态:

print("委托单状态: %s, 已成交: %d 手" % (order["status"], order["volume_orign"] - order["volume_left"]))

要撤销一个委托单, 使用 api.cancel_order() 函数:

api.cancel_order(order)

这部分的完整示例程序请见 t40.py

到这里为止, 我们已经掌握了 TqSdk 中行情和交易相关功能的基本使用. 我们将在下一节中, 组合使用它们, 创建一个交易策略程序

构建一个交易策略程序

在这一节中, 我们将创建一个简单的自动交易程序: 每当行情最新价高于最近15分钟均价时, 开仓买进. 这个程序是这样的:

klines = api.get_kline_serial("DCE.m1901", 60)
while True:
    api.wait_update()
    if api.is_changing(klines):
        ma = sum(klines.close.iloc[-15:])/15
        print("最新价", klines.close.iloc[-1], "MA", ma)
        if klines.close.iloc[-1] > ma:
            print("最新价大于MA: 市价开仓")
            api.insert_order(symbol="DCE.m1901", direction="BUY", offset="OPEN", volume=5)

上面的代码中出现了一个新函数 api.is_changing(). 这个函数用于判定指定对象是否在最近一次 wait_update 中被更新.

这部分的完整示例程序请见 t60.py

按照目标持仓自动交易

在某些场景中, 我们可能会发现, 自己写代码管理下单撤单是一件很麻烦的事情. 在这种情况下, 你可以使用 target_position 机制. 你只需要指定账户中预期应有的持仓手数, TqSdk 会自动通过一系列指令调整仓位直到达成目标. 请看例子:

# 创建 rb1810 的目标持仓 task,该 task 负责调整 rb1810 的仓位到指定的目标仓位
target_pos_near = TargetPosTask(api, "SHFE.rb1810")
# 创建 rb1901 的目标持仓 task,该 task 负责调整 rb1901 的仓位到指定的目标仓位
target_pos_deferred = TargetPosTask(api, "SHFE.rb1901")

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 > 200:
            print("目标持仓: 空近月,多远月")
            # 设置目标持仓为正数表示多头,负数表示空头,0表示空仓
            target_pos_near.set_target_volume(-1)
            target_pos_deferred.set_target_volume(1)
        elif spread < 150:
            print("目标持仓: 空仓")
            target_pos_near.set_target_volume(0)
            target_pos_deferred.set_target_volume(0)

这部分的完整示例程序请见 t80.py

在程序中画图

策略程序在天勤中运行时, 会自动获得一个专属行情图. 策略程序可以通过一些语句在这个图上绘制一些指标, 像这样:

klines_1905 = api.get_kline_serial("SHFE.cu1905", 86400)
klines_1906 = api.get_kline_serial("SHFE.cu1906", 86400)
klines_1905["dif"] = klines_1906["close"] - klines_1905["close"]

这部分的完整示例程序请见 t90.py

在策略中使用参数

如果您希望在策略中设置一些参数,在策略每次运行时输入,您只需要:

  • 用全大写字符作为参数变量名
  • 确保这些参数在TqApi创建前出现
  • 参数是整数、浮点数或字符串类型

以 doublema.py 为例:

from tqsdk import TqApi, TargetPosTask

SHORT = 30  # 短周期
LONG = 60  # 长周期
SYMBOL = "SHFE.bu1906"  # 合约代码

api = TqApi()
...

这个策略在天勤中运行时,会自动出现这样的参数输入面板:

_images/dialog_param_run.png

回测时则会出现这样的参数输入面板:

_images/dialog_param_backtest.png

开发包参考文档

要深入了解开发包的使用, 请参见文档:https://doc.shinnytech.com/pysdk/latest/reference