天勤量化开发包, 期货量化, 实时行情/历史数据/实盘交易

Overview

TqSdk 天勤量化交易策略程序开发包

TqSdk 是一个由信易科技发起并贡献主要代码的开源 python 库. 依托快期多年积累成熟的交易及行情服务器体系, TqSdk 支持用户使用极少的代码量构建各种类型的量化交易策略程序, 并提供包含期货、期权、股票的 历史数据-实时数据-开发调试-策略回测-模拟交易-实盘交易-运行监控-风险管理 全套解决方案.

from tqsdk import TqApi, TqAuth, TqAccount, TargetPosTask

api = TqApi(TqAccount("H海通期货", "4003242", "123456"), auth=TqAuth("信易账户", "账户密码"))      # 创建 TqApi 实例, 指定交易账户
q_1910 = api.get_quote("SHFE.rb1910")                         # 订阅近月合约行情
t_1910 = TargetPosTask(api, "SHFE.rb1910")                    # 创建近月合约调仓工具
q_2001 = api.get_quote("SHFE.rb2001")                         # 订阅远月合约行情
t_2001 = TargetPosTask(api, "SHFE.rb2001")                    # 创建远月合约调仓工具

while True:
  api.wait_update()                                           # 等待数据更新
  spread = q_1910["last_price"] - q_2001["last_price"]        # 计算近月合约-远月合约价差
  print("当前价差:", spread)
  if spread > 250:
    print("价差过高: 空近月,多远月")                            
    t_1910.set_target_volume(-1)                              # 要求把1910合约调整为空头1手
    t_2001.set_target_volume(1)                               # 要求把2001合约调整为多头1手
  elif spread < 200:
    print("价差回复: 清空持仓")                               # 要求把 1910 和 2001合约都调整为不持仓
    t_1910.set_target_volume(0)
    t_2001.set_target_volume(0)

要快速了解如何使用TqSdk, 可以访问我们的 十分钟快速入门指南.

Architecture

系统架构图

Features

TqSdk 提供的功能可以支持从简单到复杂的各类策略程序.

  • 公司级数据运维,提供当前所有可交易合约从上市开始的 全部Tick数据和K线数据
  • 支持市场上90%的期货公司 实盘交易
  • 支持 模拟交易
  • 支持 Tick级和K线级回测, 支持 复杂策略回测
  • 提供近百个 技术指标函数及源码
  • 用户无须建立和维护数据库, 行情和交易数据全在 内存数据库 , 无访问延迟
  • 优化支持 pandasnumpy
  • 无强制框架结构, 支持任意复杂度的策略, 在一个交易策略程序中使用多个品种的K线/实时行情并交易多个品种
  • 配合开发者支持工具,能够进行交易信号打点,支持自定义指标画图

Installation

TqSdk 仅支持 Python 3.6 及更高版本. 要安装 TqSdk, 可使用 pip:

$ pip install tqsdk

Documentation

在线阅读HTML版本文档: https://doc.shinnytech.com/tqsdk/latest

在线问答社区: https://www.shinnytech.com/qa

知乎账户【天勤量化】:https://www.zhihu.com/org/tian-qin-liang-hua/activities

用户交流QQ群: 619870862 (目前只允许给我们点过STAR的同学加入, 加群时请提供github用户名)

Gui

TqSdk本身自带的web_gui功能,简单一行参数即可支持调用图形化界面,详情参考web_gui TqSdk web_gui

About us

信易科技 是专业的期货软件供应商和交易所授权行情服务商. 旗下的快期系列产品已为市场服务超过10年. TqSdk 是公司开源计划的一部分.

Comments
  • 完善期权合约字段

    完善期权合约字段

    为了更好地调取期权合约,在tqsdk.objs.Quote中加入两个字段: product_id:用于识别基础现货资产 option_class:用于识别"认购" or "认沽" 上述字段来自于:"https://openmd.shinnytech.com/t/md/symbols/latest.json" 只是在python项目中没有调取。

    opened by gamcing 10
  • 关于 tq 的 K 线问题

    关于 tq 的 K 线问题

    最近用了一段时间 tq,也和周边其它产品对比过,发现 tq的 K 线有个问题: 跨区结束时间居然是在下一个时间段出现 ,例如11:30:00的结束 K 线是没有的,13:30:00才是11:30:00的结束线,同样,2:30和15:00的也是没有的, 例如30分钟线,TQ 的序列是这样的: 10:30:00 11:00:00 13:30:00 14:00:00 其它产品是这样的: 10:30:00 11:00:00 11:30:00 14:00:00

    我在 TQ回测中,收到13:30:00的 K 线,回测时间也是13:30:00,下单时间却是11:29:59.9999,结果就导致用将来的趋势去过去下单,出现了错误的利润。

    希望官方能告知解决办法!

    opened by zshchou 7
  • 下单后无法取到正确的成交价格,有无方法?

    下单后无法取到正确的成交价格,有无方法?

    如下的方法,下单后无法取到正确的成交价格, target_pos.set_target_volume(1) api.wait_update() while not api.is_changing(trade): 空 api.wait_update() 空 if True: #判断条件xxx 空 格 lot = position.pos 空 格 if lot>0 : 空 格 openPrice = position.open_price_long 空 格 elif lot<0: 空 格 openPrice = position.open_price_short 空 格 else: 空 格 openPrice = 0 空 格 print("openPrice",openPrice) 成交价格是延时一些毫秒后给出的。 api.is_changing(trade)触发后,position.open_price_short和position.open_price_long却没有及时更新。所以取到的价格是错误的。

    如何写判断条件xxx? 数据结构position,trade里都没有标志,是否已成交,且返回正确的成交价格。 希望能给出正确的案例。

    opened by victorzsl 5
  • [BUG?]在0.9.17的Position对象找不到pos_long和pos_short

    [BUG?]在0.9.17的Position对象找不到pos_long和pos_short

    文档写着: volume_long = None 期货公司查询的多头手数 (不推荐, 推荐使用pos_long)

    但是从0.9.17 tqsdk收到的Postion对象内容,完全找不到pos_long和pos_short,难道是漏了?

    这是收到的实际数据: <tqsdk.objs.Position object at 0x7fd54e8278d0>, D({'exchange_id': 'SHFE', 'instrument_id': 'ag1912', 'pos_long_his': 40, 'pos_long_today': 10, 'pos_short_his': 0, 'pos_short_today': 0, 'volume_long_today': 10, 'volume_long_his': 40, 'volume_long': 50, 'volume_long_frozen_today': 0, 'volume_long_frozen_his': 0, 'volume_long_frozen': 0, 'volume_short_today': 0, 'volume_short_his': 0, 'volume_short': 0, 'volume_short_frozen_today': 0, 'volume_short_frozen_his': 0, 'volume_short_frozen': 0, 'open_price_long': 4249.8, 'open_price_short': 0.0, 'open_cost_long': 3187350.0, 'open_cost_short': 0.0, 'position_price_long': 4569.8, 'position_price_short': 0.0, 'position_cost_long': 3427350.0, 'position_cost_short': 0.0, 'float_profit_long': 237150.0, 'float_profit_short': 0.0, 'float_profit': 237150.0, 'position_profit_long': -2850.0, 'position_profit_short': 0.0, 'position_profit': -2850.0, 'margin_long': 274380.0, 'margin_short': 0.0, 'margin': 274380.0, 'user_id': '135763', 'volume_long_yd': 50, 'volume_short_yd': 0, 'last_price': 4566.0})

    opened by archerhu77 5
  • 回测订阅tick后,在交易时间段刚开始下单,可能无法成交

    回测订阅tick后,在交易时间段刚开始下单,可能无法成交

    订阅了tick时,如果指定回测开始时间为一个交易时间段的开始时间 而tick未更新数据,则导致无法成交(在sim增加交易时间判断之后):当tick未更新时,quote时间停在上一个交易时间段,而回测时间在下一交易时间段开始,此时应成交 却报错”不在交易时间段内“.

    (如果订阅的是K线,或未订阅,此问题也能触发;但当quote生成频率修改为在K线生成时也同时生成,此问题则不存在。)

    opened by shinny-limin 3
  • 天勤终端的策略同品种实盘与回测 互相干扰?

    天勤终端的策略同品种实盘与回测 互相干扰?

    在天勤中运行simnow实盘, IF策略一直开启,未关闭。 前一交易日有持仓,position.pos=-1 次日,早盘前对策略进行了昨日数据的回测,检查开平仓是否一致。 检查结果近似一致,相差不大。也保留了持仓,position.pos=-1。

    随后删除回测。

    早开盘,策略继续运行, 发现持仓居然为2手空仓了。(策略每分钟打印持仓) position.pos=-2

    大约9:45的样子,策略满足平仓条件, 开始平仓,报告仅平仓1手,另1手失败。

    失败是正常的,因为simnow仅一手持仓。

    不正常的是回测似乎干扰了实盘的position.pos值。 这是否一个Bug?

    数据没有保留,请自行实验验证。

    opened by victorzsl 3
  • api.draw_line函数绘的图在天勤终端显示不正确?

    api.draw_line函数绘的图在天勤终端显示不正确?

    在策略中想利用api.draw_line绘制信号线(线段),打印日志显示开、平点数据都是正确的,但是显示出来的结果都是水平直线,不知道是sdk的bug还是天勤终端的bug,貌似“SEG”、“RAY”均不起作用,都会绘制成直线。 绘图语句示例: if longamt < prelongamt: #如果有平仓,则绘制信号线 api.draw_line(klines, lox, loy, kid, kclose, line_type="SEG", color=0xFF0000FF) print(f"cover long: lox:{lox}, loy:{loy}, lcx:{kid}, lcy:{kclose}") lox = None #开仓位置, long open x loy = None #开仓位置, long open y

    opened by xcgoo 3
  • Mac ssl 问题

    Mac ssl 问题

    使用mac mojave的时候,在pycharm中会ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)与 wss://openmd.shinnytech.com/t/md/front/mobile 的网络连接断开,请检查客户端及网络是否正常!!这个问题,请问一下,这个问题应该如何解决,谢谢。 image

    opened by kingdjf 3
  • 使用测试账号 TqSim,断网恢复以后数据没有自动更新

    使用测试账号 TqSim,断网恢复以后数据没有自动更新

    image

    版本:0.9.8 操作系统:阿里云 Centos 7

    代码:

    def main():
        symbol1 = "[email protected]"
        symbol2 = "[email protected]"
        api = TqApi(TqSim())
        account = api.get_account()
        main_x_symbol = ""
        main_y_symbol = ""
    
        k_x = api.get_kline_serial(symbol1, 60 * 60 * 24)
        k_y = api.get_kline_serial(symbol2, 60 * 60 * 24)
    
        quote_x = api.get_quote(symbol1)
        quote_y = api.get_quote(symbol2)
    
        target_pos_x = TargetPosTask(api, symbol1)
        target_pos_y = TargetPosTask(api, symbol2)
    
        count = 0
    
        with closing(api):
            while True:
                api.wait_update()
                if not api.is_changing(quote_x) and not api.is_changing(quote_y):
                    continue
                last_k_x = k_x.iloc[-1]
                last_k_y = k_y.iloc[-1]
    
                vx = last_k_x.close
                vy = last_k_y.close
                print(vx, vy)
    

    断网以后即使网络恢复了,api.wait_update() 以后代码不再被执行。

    opened by daijiahua 3
  • 最新价格监控

    最新价格监控

    quote和kline 里面都包含最新的价格, 如果只监控 最新价格的变化, 他们更新的频率是一样的吗?

    有这个需求是,如果频率一样,我就只需要关注kline里面价格的最新变化,kline结构数据比quote少很多,可能新的数据就更少了, 可以大大节约网络传输。

    但是不确定如果只关心最新价格,更新频率是否一样?

    opened by 4ever911 3
  • 如何取消合约数据的自动更新?

    如何取消合约数据的自动更新?

    比如说,

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

    while api.wait_update() 等待后,q和klines就会自动更新,但是如果我监控的数据比较多,比如我只是临时用了几个合约 5/30/dayily kline数据, 因为没有函数取消这些合约的自动更新, 是否会造成数据太多,影响网络速度?

    opened by 4ever911 3
  • 官方文档的示例就跑不通 Task was destroyed but it is pending!

    官方文档的示例就跑不通 Task was destroyed but it is pending!

    在使用天勤量化之前,默认您已经知晓并同意以下免责条款,如果不同意请立即停止使用:https://www.shinnytech.com/blog/disclaimer/ 2022-06-18 12:09:01 - INFO - 通知 : 与 wss://free-api.shinnytech.com/t/nfmd/front/mobile 的网络连接已建立 204100.0 246 Task was destroyed but it is pending! task: <Task pending coro=<TqBaseApi._windows_patch() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\baseApi.py:119> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000287C644A2E8>()]> cb=[TqBaseApi._on_task_done()]> Task was destroyed but it is pending! task: <Task pending coro=<TqApi._notify_watcher() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\api.py:3604> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000287CF30A8B8>()]> cb=[TqBaseApi._on_task_done()]> Exception ignored in: <coroutine object TqApi._notify_watcher at 0x00000287C63D35C8> Traceback (most recent call last): File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\api.py", line 3604, in _notify_watcher File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\channel.py", line 143, in anext File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\queues.py", line 161, in get File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\baseApi.py", line 50, in _call_soon File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\base_events.py", line 691, in call_soon File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\base_events.py", line 479, in _check_closed RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<TqConnect._run() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\connect.py:176> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000287CF30A9D8>()]> cb=[TqBaseApi._on_task_done()]> Task was destroyed but it is pending! task: <Task pending coro=<TqReconnect._run() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\connect.py:261> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000287C644A6D8>()]> cb=[TqBaseApi._on_task_done()]> Exception ignored in: <coroutine object TqConnect._run at 0x00000287C6374C48> Traceback (most recent call last): File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\connect.py", line 225, in _run File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\tasks.py", line 589, in sleep File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\events.py", line 726, in get_event_loop_policy File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\events.py", line 719, in _init_event_loop_policy ImportError: sys.meta_path is None, Python is likely shutting down sys:1: RuntimeWarning: coroutine 'WebSocketCommonProtocol.write_close_frame' was never awaited Task was destroyed but it is pending! task: <Task pending coro=<TqConnect._send_handler() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\connect.py:232> wait_for=> Exception ignored in: <coroutine object TqReconnect._run at 0x00000287E36762C8> Traceback (most recent call last): File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\connect.py", line 311, in _run File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\baseApi.py", line 50, in _call_soon File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\base_events.py", line 691, in call_soon File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\base_events.py", line 479, in _check_closed RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<TqReconnect._send_handler() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\connect.py:315> wait_for=> Task was destroyed but it is pending! task: <Task pending coro=<TqSymbols._run() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\symbols.py:29> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000287C644A9A8>()]> cb=[TqBaseApi._on_task_done()]> Task was destroyed but it is pending! task: <Task pending coro=<TqTradingStatus._run() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\trading_status.py:26> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000287C63DCE28>()]> cb=[TqBaseApi._on_task_done()]> Task was destroyed but it is pending! task: <Task pending coro=<BaseSim._run() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\tradeable\sim\basesim.py:78> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000287CC01F978>()]> cb=[TqBaseApi._on_task_done()]> Task was destroyed but it is pending! task: <Task pending coro=<TqWebHelper._run() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\tqwebhelper.py:80> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000287CF30AA98>()]> cb=[TqBaseApi._on_task_done()]> Task was destroyed but it is pending! task: <Task pending coro=<DataExtension._run() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\data_extension.py:82> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000287CF30AD08>()]> cb=[TqBaseApi._on_task_done()]> Exception ignored in: <coroutine object TqSymbols._run at 0x00000287C63D36C8> Traceback (most recent call last): File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\symbols.py", line 63, in _run File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\baseApi.py", line 50, in _call_soon File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\base_events.py", line 691, in call_soon File "H:\A_software\Anaconda3\envs\pp212\lib\asyncio\base_events.py", line 479, in _check_closed RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<TqSymbols._sim_handler() running at H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\symbols.py:68> wait_for=> Exception ignored in: <coroutine object TqTradingStatus._run at 0x00000287C63D37C8> Traceback (most recent call last): File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\trading_status.py", line 26, in _run File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\baseModule.py", line 47, in _run File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\baseModule.py", line 47, in File "H:\A_software\Anaconda3\envs\pp212\lib\site-packages\tqsdk\baseApi.py", line 50, in _call_soon File "H:\A_software\Anaconda3\

    opened by ArtificialZeng 1
  • Exception: 无法创建复盘服务器

    Exception: 无法创建复盘服务器

    ===简单描述=== 用文档里的代码示例,做复盘报错:Exception: 无法创建复盘服务器 (信易账户在试用有效期内,执行请求普通的行情数据没有问题)

    ===错误日志=== (py37_quant) xiao@xiao-ws:/mnt/Data/Workspace/python/ats/003_tianqin$ cd /mnt/Data/Workspace/python/ats/003_tianqin ; /usr/bin/env /mnt/Data/System/Programs/anaconda3/envs/py37_quant/bin/python /home/xiao/.vscode/extensions/ms-python.python-2021.10.1317843341/pythonFiles/lib/python/debugpy/launcher 40143 -- /mnt/Data/Workspace/python/ats/003_tianqin/01_temp/pureTest.py 在使用天勤量化之前,默认您已经知晓并同意以下免责条款,如果不同意请立即停止使用:https://www.shinnytech.com/blog/disclaimer/ Traceback (most recent call last): File "/mnt/Data/Workspace/python/ats/003_tianqin/01_temp/pureTest.py", line 4, in api = TqApi(backtest = TqReplay(date(2019,12,23)), auth=TqAuth("listplot3d", "123456")) File "/mnt/Data/System/Programs/anaconda3/envs/py37_quant/lib/python3.7/site-packages/tqsdk/api.py", line 284, in init self._setup_connection() # 初始化通讯连接 File "/mnt/Data/System/Programs/anaconda3/envs/py37_quant/lib/python3.7/site-packages/tqsdk/api.py", line 2986, in _setup_connection self._ins_url, self._md_url = self._backtest._create_server(self) File "/mnt/Data/System/Programs/anaconda3/envs/py37_quant/lib/python3.7/site-packages/tqsdk/backtest.py", line 795, in _create_server raise Exception("无法创建复盘服务器,请检查复盘日期后重试。") Exception: 无法创建复盘服务器,请检查复盘日期后重试。 Task was destroyed but it is pending! task: <Task pending coro=<TqApi._notify_watcher() running at /mnt/Data/System/Programs/anaconda3/envs/py37_quant/lib/python3.7/site-packages/tqsdk/api.py:3442> cb=[TqBaseApi._on_task_done()]> sys:1: RuntimeWarning: coroutine 'TqApi._notify_watcher' was never awaited

    ===重现步骤=== 基于这里的代码:https://doc.shinnytech.com/tqsdk/latest/usage/replay.html?highlight=%E5%A4%8D%E7%9B%98,改成下面的代码,然后运行:

    from datetime import date from tqsdk import TqApi, TqReplay,TqAuth

    api = TqApi(backtest = TqReplay(date(2019,12,23)), auth=TqAuth("listplotd", "123456")) print("hello relay") api.close()

    opened by listplot3d 1
  • 在协程里用不了get_kline_serial?

    在协程里用不了get_kline_serial?

    我用的visual studio code 也提示: Exception: TqSdk 使用了 python3 的原生协程和异步通讯库 asyncio,您所使用的 IDE 不支持 asyncio, 请使用 pycharm 或其它支持 asyncio 的 IDE 我发现只要在协程里调用get_kline_serial就会提示,在协程外面调用就不会报这个错误。 我看了一下貌似tqsdk也依赖那个事件循环,我协程本来就运行在事件循环里面,就不能共用一个事件循环嘛?

    opened by kkqy 0
Releases(3.2.12)
Owner
信易科技
上海信易信息科技股份有限公司
信易科技