简介:天勤量化开发包(TqSdk)是一套面向期货、期权、股票量化交易的Python开发工具包,服务于交易策略研究员、程序化交易开发者及金融科技学习者。它将历史数据、实时行情、策略回测、模拟交易、实盘交易、运行监控与风险管理整合为完整闭环,使用者只需少量代码即可搭建量化策略程序。资源共354个文件,压缩包约9.03MB,其中包含130个Python源码文件、71个RST文档、多个Drawio/SVG架构设计图,以及前端组件、配置脚本等;RST文档详细说明API用法,设计图梳理系统与数据流架构,目录结构清晰,便于按模块研读与二次开发。目前已有1543人学习浏览。包内还提供策略开发示例、数据流与工作流示意图、演示动图等辅助资料,可帮助快速理解调用流程与事件驱动机制,适合需要快速上手期货量化、希望从零构建交易系统的开发者作为入门与参考素材。 做期货量化开发,最磨人的往往不是策略逻辑本身,而是从行情到交易的整套基础设施。数据从哪来、延迟怎么控制、模拟盘怎么接、实盘怎么下,这些事如果全自己搭,光是柜台对接和行情解码就够喝一壶。我最早接触天勤量化开发包,就是冲着它"一个API搞定实时行情、历史数据和实盘交易"这个定位去的。用下来确实省了很多事,但中间也踩了不少坑。
这篇文章就把我实际使用天勤量化开发包做期货量化的经验整理出来,从行情订阅、历史数据到模拟盘和实盘交易,该写的代码、该注意的细节我都会提到。内容面向的是有一定Python基础、想进入期货量化但还没找到合适开发框架的人,也适合已经在用其他行情源、想对比一下开发效率的老手。
1. 为什么是天勤:一套API打通期货量化全链路
1.1 自建量化系统的三座大山
自己从零搭一套期货量化系统,首先要解决的就是行情源。国内期货市场的Tick级行情不是随随便便就能拿到的,CTP柜台给了接口,但你需要自己连行情服务器、自己解析二进制协议、自己维护重连逻辑。数据到了本地之后,还要自己组织成方便策略使用的结构,这一步对没有底层开发经验的人来说非常劝退。
第二座大山是交易接口。CTP的报单、撤单、成交回报、持仓查询,每一个都有异步消息,状态机稍微处理不好就会出乱子。如果是多账户、多策略并行,复杂度还会成倍上涨。更麻烦的是模拟盘和实盘的环境差异,同一套代码要在两套环境里都能稳定跑,这对接口抽象能力要求极高。
第三座大山是历史数据。回测需要高质量分钟K线,实盘需要实时拼接,数据复权、主力连续合约的切换、节假日和夜盘的缺口,这些都是坑。很多人的量化之路就卡在了这里——策略还没写,数据先搞了一个月。
1.2 天勤到底做了什么
天勤量化开发包的设计思路,是把上面三座大山统一在一个Python库和网关进程里解决。它由两部分组成:一是TqGateway网关程序,二是tqsdk这个Python库。网关负责和期货公司柜台、行情服务器通信,Python库负责把行情、交易、数据都以对象形式暴露给策略。
这意味着你不需要关心CTP协议长什么样,不需要自己写数据解码,也不需要操心断线重连。一条api.get_quote()就能拿到实时盘口,一条api.get_kline_serial()就能拿到分钟级K线,一条api.insert_order()就能完成报单。开发效率的提升不是一点点,而是把几周的工作量压缩到一天甚至几小时。
天勤还有账号体系,使用前需要注册快期账号并完成授权。行情有行情授权,交易有交易授权,这个机制保证了它的数据服务是可持续的,同时也在入口就过滤掉了大部分滥用行为。刚开始可能会觉得多一步注册很麻烦,但实际注册完五分钟左右就能跑通全部功能,门槛并不高。
2. 环境准备与快速上手:从安装到拿到第一个行情
2.1 安装与账号准备
天勤量化开发包的安装和普通Python库没有区别,直接用pip装就行:
pip install tqsdk装完之后,去快期官网注册一个账号,然后在个人中心里开通天勤相关的服务权限。这一步很重要,因为后面所有API调用都需要传入TqAuth对象做身份认证。权限开通通常几分钟内就会生效,偶尔遇到延迟可以等半小时再试。
我建议在正式写策略之前,先把环境验证一下。用一个最小的行情程序跑通,确认账号没问题、网络能连通,再往后面走。这一步看似简单,实际上能帮你区分"代码问题"和"账号问题",省下后面大量排查时间。
Python版本方面,官方支持3.7以上的版本,我目前用3.10和3.11都没有遇到兼容性问题。操作系统的话,Windows、Linux、macOS都能用,但如果跑在云服务器上,建议用Linux,长期运行的稳定性会好很多。
2.2 实时行情订阅:三行代码跑起来
实时行情是天勤最基础也最核心的能力。下面这段代码可以订阅螺纹钢主力合约的实时行情:
from tqsdk import TqApi, TqAuth api = TqApi(auth=TqAuth("你的快期账号", "你的快期密码")) quote = api.get_quote("SHFE.rb2310") while True: api.wait_update() if quote.datetime: print("最新价:", quote.last_price, "时间:", quote.datetime)合约代码的格式需要注意,交易所前缀不能省。上期所是SHFE,大商所是DCE,郑商所是CZCE,中金所是CFFEX,上海能源中心是INE,广期所是GFEX。比如SHFE.rb2310表示上期所螺纹钢2310合约,DCE.m2401表示大商所豆粕2401合约,CZCE.CF405表示郑商所棉花405合约。
这里有个新手特别容易踩的坑:很多人以为get_quote返回一个字典,直接打印就能看到所有数据。天勤里的quote、K线、账户、持仓这些核心对象,内部实现是"引用型"的,数据会通过wait_update()持续更新。在同一时刻访问它的属性,拿到的是当前最新的快照值。这种设计的好处是策略代码非常直观,坏处是一旦忘了调用wait_update(),行情就永远不刷新。
2.3 wait_update()真的是个循环
上面代码里的while True + wait_update()是整个天勤的事件循环核心。每次调用wait_update(),Python库会阻塞等待并处理至少一个数据包,这些数据包可能是行情推送、成交回报、持仓变化,也可能是你在本地修改某个对象后产生的操作指令。
理解这一点之后,写策略时的思路就会清晰很多:所有依赖行情变化的逻辑,都必须放在循环内、等待wait_update()返回之后执行。比如你想在价格突破某个阈值时开仓,判断条件一定要写在wait_update()之后,不能在循环外只判断一次。
性能方面,如果策略逻辑比较复杂,每次wait_update()返回后要处理大量计算,可以考虑把行情的处理频率降低,比如只在新的Tick到来时才做计算。天勤的quote对象里有一个datetime字段,记录的是最新行情时间,你可以记录上一次处理的时间,当时间变化时才执行策略逻辑,避免在同一个行情时间戳上反复计算。
3. 历史数据:给策略喂饱"过去"
3.1 三种获取方式,按需选择
天勤提供三种获取历史数据的途径,适用场景完全不同。
第一种是api.get_kline_serial(),这是最常用的。它可以获取从当前时刻往前回溯的连续K线,并且会在后续的wait_update()循环中实时更新最新一根K线。这种方式适合实盘策略使用,因为返回的K线序列本身就带着实时更新能力,策略拿到手直接就能判断当前价格状态。
第二种是api.get_kline_data(),用于一次性拉取一段历史K线,适合做离线数据分析和策略回测。它不随实时行情更新,拉完就是静态数据。数据周期可以从秒级到日线,非常灵活。
第三种是直接用天勤数据服务提供的批量下载工具,适合要拉很长时间跨度的历史数据做研究的场景。不过这个需要额外开通数据服务权限,普通用户一般用前两种就足够了。
3.2 K线序列实战:DataFrame带来的便利
get_kline_serial()返回的是一个pandas DataFrame,这是天勤非常友好的一个设计。你拿到的数据天然就能用pandas去处理,做技术指标计算时可以直接用向量化操作,不需要自己维护K线数组。
一个典型的历史数据获取代码如下:
from tqsdk import TqApi, TqAuth api = TqApi(auth=TqAuth("账号", "密码")) # 获取螺纹钢主连的5分钟K线,最近500根 klines = api.get_kline_serial("SHFE.rb2310", duration_seconds=300, data_length=500) while True: api.wait_update() # klines会持续更新,最后一根是当前未走完的K线 closed_bar = klines.iloc[-2] # 上一根已收盘的K线 current_price = klines.iloc[-1]["close"] print("上一根收盘价:", closed_bar["close"], "当前最新价:", current_price)关于duration_seconds参数,它控制K线周期,单位是秒。天勤直接支持任意秒数的自定义周期,不局限于标准的1分钟、5分钟、15分钟。比如你要30秒的K线,传duration_seconds=30即可。常见的周期对照:1分钟是60,5分钟是300,15分钟是900,1小时是3600,日线是86400。
data_length控制返回的K线数量,注意它是指"最多保留多少根",不是"从哪个时间点开始"。天勤会返回从最早可取时间到当前时刻的K线,但数量不超过data_length。如果你要研究很久以前的数据,data_length要设置足够大。
K线DataFrame的列包括:datetime、open、high、low、close、volume、open_oi、close_oi。其中datetime是天勤自己定义的纳秒级时间戳,显示出来是超长整数,想转成可读时间要用pd.to_datetime()处理。volume是成交量,open_oi和close_oi分别是开盘持仓量和收盘持仓量,做持仓量分析时会用到。
有一次我用get_kline_serial拉日线做回测,发现最后一根K线的最高价和最低价总在变化,一开始以为数据出错了。后来才意识到,最后一根是当日正在生成的K线,盘中肯定会随着行情变化而变化。这是很多新手会困惑的点。如果你想拿"已收盘"的K线做判断,一定要用iloc[-2]而不是iloc[-1]。
3.3 关于A股历史数据的补充说明
如果你关注的是A股历史数据,天勤其实也提供了一定的支持。在创建API时传一个_stock=True参数,就能订阅股票行情和K线,合约代码格式类似SSE.600000、SZSE.000001。也就是说你可以用天勤统一的数据接口,同时拿到期货和股票的分钟级数据用于研究和追踪。
不过要说明的是,天勤的核心战场始终在期货交易链路,股票方向主要用于行情获取,下单通道并不在这个框架内。如果你做的是A股日线级别的分析,用tushare、akshare这类专门的数据社区会方便得多;但当你同时需要期货分钟数据和股票分钟数据、并且想用同一套API维护时,天勤这个_stock模式还是值得一试的。它最大的价值在于统一了数据格式和获取逻辑,省去了在多个数据源之间来回切换的麻烦。
4. 模拟盘与实盘交易:从策略到账户
4.1 接入方式:模拟盘优先
天勤支持三种账户模式。最简单的是TqSim(),也就是天勤自带的仿真撮合账户,不需要外部账号,直接本地运行。它的撮合逻辑比较接地气,是根据盘口价格和成交量模拟真实撮合,不是"永远以对手价成交"的理想模型,所以策略在TqSim上的表现比很多粗糙的模拟环境更有参考价值。
第二种是接入外部模拟柜台(比如期货公司提供的仿真账号),用TqAccount指定期货公司名称、资金账号、密码即可连接。第三种就是实盘账户,同样用TqAccount接入,但连接的是真实柜台,账号密码是期货公司开户得到的资金账号和密码。
这里有个容易混淆的地方:TqAccount里的账号是期货公司的资金账号,不是快期账号。快期账号是你在天勤平台的登录凭证,两者各管各的。我第一次接实盘时在这卡了快半小时,一直用快期账号去连期货公司,自然连不上。
4.2 下单、撤单与持仓查询
下单的核心接口是insert_order,一个比较完整的示例:
from tqsdk import TqApi, TqAccount, TqAuth api = TqApi( TqAccount("你的期货公司", "资金账号", "资金密码"), auth=TqAuth("快期账号", "快期密码") ) # 下单:买入开仓1手螺纹钢,限价3800 order = api.insert_order( symbol="SHFE.rb2310", direction="BUY", offset="OPEN", volume=1, limit_price=3800.0 ) while True: api.wait_update() if order.status == "FINISHED": print("订单已完成,成交均价:", order.trade_price) break elif order.status == "REJECTED": print("订单被拒绝,原因:", order.message) breakdirection有BUY和SELL两种,offset有OPEN(开仓)、CLOSE(平仓)、CLOSETODAY(平今仓)三种。国内商品期货有平今和平昨的区分,天勤的offset参数直接支持这种语义,算是对国内交易制度适配得比较到位的地方。
订单状态可以通过order.status判断,常见的有ALIVE(已报)、FINISHED(已完成)、REJECTED(已拒绝)。撤单用api.cancel_order(order),如果撤单成功,订单状态会变为FINISHED,但成交量为0。
查询资金和持仓也很直接。api.get_account()返回账户权益、可用资金、冻结保证金、手续费等信息;api.get_position()返回持仓信息,包括持仓量、开仓均价、今持仓量等。实盘交易中,我习惯在每次下单后立即检查账户可用资金,避免因为资金不足导致报单被拒。这里额外提醒一句:我这个接口的用法只是技术演示,不构成任何投资建议,大家做量化一定要把资金管理放在策略之前。
4.3 风控与异常处理
实盘和模拟最大的区别,就是"亏的是真钱"。天勤提供了完善的基础工具,但风控逻辑得靠策略自己写。我的建议是至少做好三层风控。
第一层是报单前检查。下单前检查账户可用资金是否足够、持仓是否超限、当前是否在可交易时段。天勤的quote对象里有一个volume字段,如果为0说明当前没有行情推送(通常意味着非交易时段或合约不活跃),此时下单很可能会被柜台拒绝。
第二层是运行中监控。用api.get_trade()及时获取成交回报,记录每笔成交的价格和数量,实时计算策略的盈亏情况。当亏损超过预设阈值时,策略应该自动执行止损或暂停开仓。这个逻辑不要放在策略的"赚钱模块"里,要独立出来,让它无条件执行。
第三层是程序异常兜底。实盘程序崩溃是必然会发生的事,不是"如果"而是"什么时候"。你可以给程序加一个看门狗脚本,定时检查策略进程是否存活,挂了就自动重启。下单和撤单的逻辑要设计成"幂等"的,避免程序重启后重复下单。天勤的本地订单号可以帮你做这种去重,但需要你在代码里维护好。
5. 常见问题与排坑实录
5.1 新手最容易踩的坑汇总
我在实际开发和用户交流中遇到最多的问题,下面用表格整理出来,方便大家对照排查:
| 现象 | 大概率原因 | 解决办法 |
|---|---|---|
| 初始化API时提示授权失败 | 快期账号未开通权限,或账号密码错误 | 检查快期账号是否正确,确认已开通天勤服务权限 |
| 行情一直不更新 | 忘记调用wait_update(),或没有订阅任何行情对象 | 把wait_update()放进事件循环,确认调用了get_quote或get_kline_serial |
| 合约代码报错 | 合约代码少了交易所前缀,或代码格式不对 | 确认代码形如SHFE.rb2310、DCE.m2401、CZCE.CF405 |
| K线最后一根不停跳动 | 把未收盘的K线当成了完整K线 | 用klines.iloc[-2]取上一根已收盘K线 |
| 实盘下单连接失败 | TqAccount传成了快期账号 | 确认传的是期货公司资金账号和密码 |
| 订单状态一直是ALIVE | 限价单价格偏离市价太远,或非交易时段 | 检查限价是否合理,确认当前是否有行情(quote.volume > 0) |
| 程序运行一段时间后卡死 | 事件循环里没有合理控制处理频率,数据堆积 | 简化wait_update()之后的计算逻辑,避免在循环内做耗时操作 |
5.2 我的个人体会
用天勤做了快一年期货量化,最大的感受是:这个工具把量化开发的"体力活"压缩到了很小一部分,让我能把精力花在真正的策略研究上。它当然不是完美的,比如大量wait_update()循环的编程方式和异步模型的思维习惯不同,需要一段时间适应;再比如文档里有些细节写得不那么直白,得靠实验去验证。
不过这些缺点在整个开发效率面前都不算大问题。如果你正在犹豫选什么量化开发框架,我建议先从TqSim模拟账户开始跑,把行情、策略、下单、风控全链路走通,再考虑实盘。等你在模拟环境里把该踩的坑都踩完了,实盘的时候会从容很多。踩过几次"模拟盘没事、实盘出事"的教训之后,你就会明白我为什么反复强调:先跑通,再上真钱。
本文还有配套的精品资源,点击获取