- 金融科技
【免费下载链接】tqsdk-python
天勤量化开发包, 期货量化, 实时行情/历史数据/实盘交易
本文以 tqsdk-python 的tqsdk.lib业务工具库为对象,系统讲解天勤量化开发包中三个核心交易辅助工具的完整用法:负责接收服务器通知的TqNotify、负责把指定合约自动调整到目标净持仓的TargetPosTask,以及基于时间维度批量调度调仓任务的TargetPosScheduler。读完本文,你将掌握目标持仓自动调仓、大单拆分、追价撤单重下、TWAP/VWAP 式时间表调度等实战能力,并理解这些工具底层"下单/撤单/追单"的驱动机制。
一、认识 tqsdk.lib:业务工具库的构成
在 tqsdk-python 中,tqsdk.lib是与行情、账户等基础数据层相对独立的"业务工具层",它把交易中高频复用的逻辑封装成开箱即用的工具类。从源码结构看,模块共由四个文件组成(参见 tqsdk/lib/init.py):
- tqsdk/lib/notify.py:提供
TqNotify,用于在同步代码中接收服务器主动推送的通知; - tqsdk/lib/target_pos_task.py:提供
TargetPosTask(目标持仓工具)以及内部使用的InsertOrderUntilAllTradedTask(追价下单)与InsertOrderTask(下单); - tqsdk/lib/target_pos_scheduler.py:提供
TargetPosScheduler,基于时间表批量调度TargetPosTask; - tqsdk/lib/utils.py 与 tqsdk/lib/time_table.py:分别提供参数校验函数(如
_check_offset_priority、_check_volume_limit)和TqTimeTable数据结构。
这些类在包顶层均有导出(见 tqsdk/init.py),因此使用时可直接from tqsdk import TqNotify, TargetPosTask, TargetPosScheduler。下面是各工具的设计定位:
| 工具类 | 设计定位 |
|---|---|
TqNotify | 在同步代码中接收服务器通知,每次可拉取自上次读取以来的新增通知 |
TargetPosTask | 将某合约调整到目标净持仓手数,自动完成下单、撤单、追单 |
TargetPosScheduler | 依据time_table(pandas DataFrame 时间表)按时间维度依次执行多个调仓任务 |
InsertOrderUntilAllTradedTask/InsertOrderTask | 内部追价/下单任务,实现"行情变化自动撤单重下直到全部成交",主要在库内部使用 |
二、TqNotify:同步代码中收集服务器通知
2.1 用途与基本用法
TqNotify(源码见 tqsdk/lib/notify.py)解决的是"通知推送与同步主循环"的对接问题:tqsdk 的主循环是api.wait_update(),而服务器通知(如风控、成交提示等)需要被主动收集。它构造一次实例后,通过get_notifies()每次拉取距离上次调用之后新产生的通知列表,没有新通知则返回空列表:
from tqsdk import TqApi, TqAuth, TqKq, TqNotify api = TqApi(account=TqKq(), auth=TqAuth("快期账户", "账户密码")) tq_notify = TqNotify(api) # 构造实例 while True: api.wait_update() # 返回距离上一次调用 get_notifies() 之后产生的通知列表,没有则返回 [] notify_list = tq_notify.get_notifies() for notify in notify_list: print(notify) # 打印通知内容 # send_message(notify['content']) # 可在此把通知转发到其他工具2.2 底层工作机制
从源码实现看(tqsdk/lib/notify.py),TqNotify在构造时通过api.create_task(self._run())启动一个后台协程,该协程调用register_update_notify订阅数据中的notify节点:每当wait_update()触发更新,协程就对比"已处理通知集合"与当前全部通知集合,把新增通知追加到未读列表_unread_notifies_list中;get_notifies()则从该列表中取出通知内容并清空列表。
值得注意的细节:源码注释明确指出,未读通知采用 list 类型,尽量保证用户读到通知的顺序与进程收到的顺序一致,但不能完全保证——即对通知顺序有严格依赖的应用需要自行处理排序。另外_unread_notifies_list在初始化时会把构造时已存在的通知直接放入未读列表,因此实例创建后第一次调用get_notifies()也能拿到存量通知。
三、TargetPosTask:目标持仓自动调仓工具
3.1 核心概念与最小示例
TargetPosTask是业务工具库中最重要的工具:创建一个实例后,只需调用set_target_volume()设定目标净持仓手数,工具即在后台负责把该合约(默认为整个账户的该合约净持仓)调整到目标头寸。最小使用示例:
from tqsdk import TqApi, TqAuth, TargetPosTask api = TqApi(auth=TqAuth("快期账户", "账户密码")) target_pos = TargetPosTask(api, "SHFE.rb2610") # 创建自动调仓工具,负责调整 SHFE.rb2610 持仓 target_pos.set_target_volume(5) # 要求调整到多头 5 手 while True: # 需在 set_target_volume 后调用 wait_update() 以发出指令 api.wait_update()set_target_volume()的参数volume语义为:正数表示多头、负数表示空头、0 表示空仓(见 tqsdk/lib/target_pos_task.py 中set_target_volume的 docstring)。同一实例可反复调用该方法修改目标,工具总是以最后一次设置的手数为工作目标。
3.2 构造参数全解
TargetPosTask.__init__的完整签名如下(tqsdk/lib/target_pos_task.py):
TargetPosTask(api, symbol, price="ACTIVE", offset_priority="今昨,开", min_volume=None, max_volume=None, trade_chan=None, trade_objs_chan=None, account=None, support_open_min_volume=False, target_volume_chan=None)各参数含义与取值范围:
- api(必填):
TqApi实例,该 task 依托指定 api 下单/撤单。 - symbol(必填):负责调整的合约代码,格式为
交易所代码.合约代码,如"SHFE.cu2012"。 - price(可选,默认
"ACTIVE"):下单方式,三种取值:"ACTIVE":对价下单。调整过程中若下单方向为买,对价为卖一价;若为卖,对价为买一价,能较快成交;"PASSIVE":排队价下单。买时对价为买一价、卖时对价为卖一价,挂单更"被动",但可能造成较多撤单;Callable[[str], Union[float, int]]:自定义价格函数,参数为下单方向,返回值为下单价格;若函数返回 nan,程序会抛错。
- offset_priority(可选,默认
"今昨,开"):开平仓顺序,昨=平昨仓,今=平今仓,开=开仓,逗号=等待之前操作完成。参数在构造时由_check_offset_priority(tqsdk/lib/utils.py)校验,只允许今/昨/开与逗号组合。常用取值:"今昨,开":先平今仓,再平昨仓,等待平仓完成后开仓,适合无单向大边保证金的品种,避免开仓保证金不足;"今昨开":先平今仓、再平昨仓、并开仓,所有指令同时发出,适合有单向大边的品种;"昨开":先平昨仓再开仓,禁止平今仓,适合股指这类平今手续费较高的品种;"开":只开仓不平仓,适合需要锁仓操作的品种。
- min_volume / max_volume(可选,默认不启用):大单拆分模式下每笔最小/最大下单手数。两者必须同时填写,且需满足
max_volume >= min_volume > 0(由_check_volume_limit校验,见 tqsdk/lib/utils.py)。 - trade_chan(可选):成交通知 channel,有成交发生时将成交手数(多头为正数、空头为负数)发送到该 channel。
- trade_objs_chan(可选):成交对象通知 channel,有成交发生时将成交对象发送到该 channel。
- account(可选):指定发送下单指令的账户实例(
TqAccount/TqKq/TqSim)。多账户模式下该参数必须指定,否则构造会抛出异常。 - support_open_min_volume(可选,默认 False):是否支持有最小开仓手数限制的合约,详见 3.5 节。
- target_volume_chan(可选):高级用法,仅供
TargetPosScheduler内部使用,外部不应直接使用。当本轮调仓任务结束时通过该 channel 发送目标持仓手数,用于通知调度器继续后续调度。
3.3 price 自定义函数示例
当使用函数式price时,函数接收下单方向"BUY"/"SELL"并返回价格。源码 docstring 提供了两个典型模式:在 BUY 时用买一价加一档、SELL 时用卖一价减一档;或用涨跌停价报单:
quote = api.get_quote("SHFE.cu2012") def get_price(direction): # BUY 时使用买一价加一档,SELL 时使用卖一价减一档 if direction == "BUY": price = quote.bid_price1 + quote.price_tick else: price = quote.ask_price1 - quote.price_tick if price != price: # 如果 price 是 nan,用最新价报单 price = quote.last_price return price target_pos = TargetPosTask(api, "SHFE.cu2012", price=get_price)注意,若自定义价格函数返回 nan,程序会直接抛错(见InsertOrderUntilAllTradedTask._run中的检查逻辑),所以函数内应像上例一样做 nan 兜底。
3.4 大单拆分模式
同时设置min_volume与max_volume即启用大单拆分模式(源码 docstring 的"注意 4")。其逻辑为:调用set_target_volume后,先按目标持仓手数与开平仓顺序计算出需要平今、平昨、开仓的目标下单手数及顺序,然后:
- 若调整持仓的目标下单手数小于
max_volume,直接以目标下单手数下一笔单; - 若目标下单手数大于等于
max_volume,则以min_volume与max_volume之间的随机正整数下一笔委托单,全部成交后继续处理剩余手数,如此循环,直到剩余手数小于max_volume时以剩余手数直接下单。
从InsertOrderUntilAllTradedTask._run的实现可以看到随机手数的具体来源:当min_volume与max_volume均设置且剩余手数>= max_volume时,本笔手数为utils.RD.randint(min_volume, max_volume)(tqsdk/lib/target_pos_task.py)。这种模式用于降低单笔大单对市场的冲击,配合对价/排队价使用效果更好。示例:
from tqsdk import TqApi, TqAuth, TargetPosTask api = TqApi(auth=TqAuth("快期账户", "账户密码")) position = api.get_position('SHFE.rb2106') # 同时设置 min_volume、max_volume 即表示使用大单拆分模式,每笔手数在 2~10 之间随机 t = TargetPosTask(api, 'SHFE.rb2106', min_volume=2, max_volume=10) t.set_target_volume(50) while True: api.wait_update() if position.pos_long == 50: break api.close()3.5 最小开仓手数限制合约(support_open_min_volume)
默认情况下,TargetPosTask不支持交易所规定最小开仓手数的合约:若合约的open_min_market_order_volume或open_min_limit_order_volume大于 1,创建后的调仓任务会在后续wait_update()中抛出异常。如需支持,可设置support_open_min_volume=True,启用后的行为(源码与 doc/usage/targetpostask.rst 中均有说明):
- 仍会根据行情变化撤单重报,但最终持仓只能保证满足
|当前持仓手数 - 目标持仓手数| < quote.open_min_limit_order_volume; - 当开仓追单剩余手数小于
open_min_limit_order_volume时,该次开仓追单直接结束、不再报单; - 若同时启用大单拆分,
min_volume、max_volume都必须大于等于open_min_limit_order_volume,否则直接抛异常; - 若
offset_priority="开"且本次需开仓的总手数本身小于open_min_limit_order_volume,则不会发单,本轮调仓任务直接结束。
启用后判断调仓是否完成的推荐写法:
from tqsdk import TqApi, TqAuth, TargetPosTask api = TqApi(auth=TqAuth("快期账户", "账户密码")) symbol = "GFEX.ps2704" target_volume = 20 quote = api.get_quote(symbol) position = api.get_position(symbol) target_pos = TargetPosTask(api, symbol, support_open_min_volume=True) target_pos.set_target_volume(target_volume) while True: api.wait_update() if abs(position.pos - target_volume) < quote.open_min_limit_order_volume: print(f"调仓手数为 {target_volume} 的调仓任务已完成,当前持仓 {position.pos}") break api.close()3.6 单例约束:同一账户同一合约只能有一个实例
TargetPosTask使用元类TargetPosTaskSingleton保证每个账户下每个合约只能有一个实例,且构造参数不可修改。若对同一symbol用不同参数再次构造,会抛出明确异常,例如:
- 用不同的
offset_priority、price、min_volume、max_volume、support_open_min_volume等参数再次构造时,报错并提示"参数原为 X,现为 Y"; - 用不同的
trade_chan、trade_objs_chan、target_volume_chan对象再次构造时报错(按对象 id 比较)。
因此,如果确实需要对同一合约换用不同参数(例如把 PASSIVE 模式换成 ACTIVE 模式),必须先调用cancel()销毁现有实例,再创建新实例。
3.7 取消与结束状态:cancel / is_finished
cancel():取消当前实例,会撤销该实例已发出但未成交的委托单;取消后该实例的set_target_volume()不再生效。is_finished():返回实例是否已结束。已结束的实例不会再下单或撤单,后续调用set_target_volume()会报错(源码中会断言self._task.done())。
典型场景是:用 PASSIVE 模式调仓,希望在收盘前撤掉所有挂单并平仓,然后改用 ACTIVE 模式。完整示例(同步写法)见 doc/advanced/targetpostask2.rst:
from datetime import datetime, time from tqsdk import TqApi, TqAuth, TargetPosTask api = TqApi(auth=TqAuth("快期账户", "账户密码")) quote = api.get_quote("SHFE.rb2701") target_pos_passive = TargetPosTask(api, "SHFE.rb2701", price="PASSIVE") while datetime.strptime(quote.datetime, "%Y-%m-%d %H:%M:%S.%f").time() < time(14, 50): api.wait_update() # ... 策略代码 ... # 取消 TargetPosTask 实例 target_pos_passive.cancel() while not target_pos_passive.is_finished(): # 等待 cancel 处理结束 api.wait_update() # wait_update() 会执行撤单 # 创建新的 TargetPosTask 实例 target_pos_active = TargetPosTask(api, "SHFE.rb2701", price="ACTIVE") target_pos_active.set_target_volume(0) # 平所有仓位 while True: api.wait_update() # ... 策略代码 ... api.close()异步代码中的用法类似:await target_pos_passive等待其处理 cancel 结束(TargetPosTask实现了__await__,等待内部_wait_task_finishedfuture 完成)。
3.8 多账户模式
在多账户模式下(TqMultiAccount),调仓工具必须显式指定account参数,否则构造时报错"多账户模式下, 需要指定账户实例 account"。一个多账户调仓示例(来自源码 docstring):
from tqsdk import TqApi, TqAccount, TqMultiAccount, TqAuth, TargetPosTask account1 = TqAccount("H海通期货", "123456", "123456") account2 = TqAccount("H宏源期货", "654321", "123456") api = TqApi(TqMultiAccount([account1, account2]), auth=TqAuth("快期账户", "账户密码")) # 多账户模式下,调仓工具需要指定账户实例 target_pos1 = TargetPosTask(api, "DCE.m2105", account=account1) target_pos2 = TargetPosTask(api, "DCE.i2101", account=account2) target_pos1.set_target_volume(30) target_pos2.set_target_volume(80) while True: api.wait_update() api.close()3.9 底层工作流程
从源码结构(tqsdk/lib/target_pos_task.py)可以梳理出TargetPosTask的核心工作流程:
- 构造时启动三个后台任务:主调仓任务
_target_pos_task、行情时间记录任务_update_time_from_md,并注册任务结束回调; set_target_volume()只把目标手数发送到内部 channel_pos_chan,并不直接下单/撤单——实际动作在之后的每次wait_update()中执行,因此必须保证设置目标后主循环持续运行;- 主调仓任务读取目标手数后,先判断当前是否处于可交易时间段(回测场景用
_tqsdk_backtest的时间判断,实盘用 quote 行情时间判断),不在交易时段内则等待行情更新; - 计算出与当前净持仓的差值
delta_volume,按offset_priority的优先级顺序逐项调用_get_order得到 (报单开平标志、方向、手数),再交由InsertOrderUntilAllTradedTask执行;遇到逗号则等待此前所有报单任务全部成交; - 每个
InsertOrderUntilAllTradedTask内部:先按price模式计算限价并报单,同时启动价格监控任务;行情变化后若买单新价高于原价(或卖单新价低于原价),立即撤单并按最新价重新下单,直到全部成交;父任务被 cancel 时主动撤掉未成交挂单。
InsertOrderUntilAllTradedTask与InsertOrderTask的构造参数与TargetPosTask高度一致(api、symbol、direction、offset、volume、min/max_volume、price、trade_chan、trade_objs_chan、account),InsertOrderTask额外支持limit_price(默认市价单)与order_chan(委托单通知 channel)。两者的源码注释均明确"此类主要在 tqsdk 内部使用,并非简单用法,不建议用户直接使用"。
必须遵守的使用禁忌:请勿在使用TargetPosTask的同时混用insert_order()函数,否则将导致TargetPosTask报错或错误下单(详见 3.9 的工作流程——两类下单方式会互相干扰持仓计算)。
四、TargetPosScheduler:基于时间维度的目标持仓调度
4.1 设计动机
对于复杂的下单策略(如 TWAP 基于时间拆分手数、VWAP 基于成交量拆分手数),单独用TargetPosTask构造很不方便。TargetPosScheduler允许用户用一个time_table(pandas DataFrame)描述"什么时间、调整到多少持仓、用什么价格模式",然后按行依次调度TargetPosTask完成整个策略。源码定义见 tqsdk/lib/target_pos_scheduler.py,配套说明见 doc/advanced/scheduler.rst。
4.2 time_table:目标持仓任务列表
time_table必须是pandas.DataFrame类型,每一行表示一项目标持仓任务,按顺序逐项执行,必须包含以下三列(由_check_time_table在构造时校验,缺列会抛"缺少必要的列"异常):
- interval:当前任务的持续时间长度,单位秒。经过这么多秒后该任务退出,剩余未调整到的目标持仓留到下一项任务。
- 注意 1:最后一项任务不受时间参数控制,会按当前项参数调整到目标持仓后立即退出;
- 注意 2:时间长度可以跨非交易时间段(可以跨小节等待),但不可以跨交易日。
- target_pos:当前任务的目标净持仓手数,必须为整数(
_check_time_table校验其为整型且非空)。 - price:当前任务的下单价格模式,非 None 的项会作为创建
TargetPosTask实例的price参数。支持四种取值:None:不下单,表示暂停一段时间;"PASSIVE":排队价下单;"ACTIVE":对价下单;Callable (direction: str) -> Union[float, int]:自定义价格函数,返回 nan 会抛错。
4.3 构造参数与执行流程
TargetPosScheduler(api, symbol, time_table, offset_priority="今昨,开", min_volume=None, max_volume=None, trade_chan=None, trade_objs_chan=None, account=None, support_open_min_volume=False)其中symbol、offset_priority、min_volume、max_volume、trade_chan、trade_objs_chan、account、support_open_min_volume会直接传给内部创建的TargetPosTask,参数含义与校验规则与 3.2 节完全一致,需按TargetPosTask的说明设置。
执行流程(源码_run方法):构造时先取合约 quote,把interval列转换为deadline(结束时间的纳秒时间戳,由 tqsdk/lib/utils.py 的_get_deadline_from_interval结合交易日时间表计算);随后逐行遍历time_table:
- 若该行
price为None,暂停,不创建调仓任务; - 否则创建一个
TargetPosTask实例(传入target_volume_chan用于接收完成信号)并set_target_volume(target_pos); - 非最后一项:监听 quote 更新直到行情时间超过该行
deadline,即取消当前调仓任务进入下一项; - 最后一项:如果存在调仓任务,等待其通过
target_volume_chan通知目标手数达成后退出;若最后一项price为None(不下单),则立即退出。
4.4 简单示例
from pandas import DataFrame from tqsdk import TqApi, TqAuth, TargetPosScheduler api = TqApi(auth=TqAuth("快期账户", "账户密码")) time_table = DataFrame([ [25, 10, "PASSIVE"], [5, 10, "ACTIVE"], [25, 20, "PASSIVE"], [5, 20, "ACTIVE"], ], columns=['interval', 'target_pos', 'price']) scheduler = TargetPosScheduler(api, 'SHFE.cu2112', time_table=time_table) while True: api.wait_update() if scheduler.is_finished(): break # 打印全部成交及成交均价 print(scheduler.trades_df) average_trade_price = sum(scheduler.trades_df['price'] * scheduler.trades_df['volume']) / sum(scheduler.trades_df['volume']) print("成交均价:", average_trade_price) api.close()上述时间表表达的策略依次为:先用排队价把SHFE.cu2112调到 10 手、25 秒后退出(无论是否达成);再对价继续调到 10 手、5 秒后退出(若上一步已达成则本步只等待);再用排队价调到 20 手、25 秒后退出;最后用对价调到 20 手并等待达成后退出。
4.5 成交记录与取消
TargetPosScheduler实例提供trades_df属性,它是一张 pandas DataFrame,保存该实例产生的所有成交记录(列结构与Trade对象字段一致,由内部_trade_recv协程从trade_objs_chan汇总),可用于事后计算 VWAP 等绩效指标。控制接口:
cancel():取消当前实例,会撤销已发出但未成交的委托单;is_finished():返回实例是否已结束(内部即self._task.done()),结束后不会再发出下单或撤单动作。
4.6 与算法模块配合:twap_table 与 vwap_table
TargetPosScheduler常与算法模块配合使用。tqsdk/algorithm/time_table_generater.py 提供了两个现成的时间表生成函数(在 tqsdk/algorithm/init.py 中导出):
twap_table(api, symbol, target_pos, duration, min_volume_each_step, max_volume_each_step, account=None):生成基于时间平均加权(TWAP)的time_table。将总调整手数按单步手数上下限随机拆分成手数序列,把duration秒拆分成随机时间间隔序列(要求平均每次下单间隔不小于 3 秒,否则抛异常),每步先以 PASSIVE 排队价挂单、最后 2 秒改用 ACTIVE 对价追单。vwap_table(api, symbol, target_pos, duration, account=None):生成基于成交量加权(VWAP)的time_table。duration必须是 60 的整数倍;其逻辑是采样最近 10 个交易日内相同时间段(以当前行情时间的下一分钟为起点)的 1 分钟 K 线成交量占比,将总调整手数按比例分配,同样采用"每 60 秒前 58 秒排队价、后 2 秒对价"的节奏。
一个完整的 TWAP 策略示例(可参考 doc/advanced/scheduler.rst):
import pandas from pandas import DataFrame from tqsdk import TqApi, TqAuth, TargetPosScheduler from tqsdk.algorithm import twap_table api = TqApi(auth=TqAuth("快期账户", "账户密码")) # 目标持仓 -100 手,600s 内完成,每步 1~5 手 time_table = twap_table(api, "CZCE.MA609", -100, 600, 1, 5) # 定制化调整:在头部加一行,让第一项任务延迟 10s 再开始下单(price=None 表示不下单) time_table = pandas.concat([ DataFrame([[10, 10, None]], columns=['interval', 'target_pos', 'price']), time_table ], ignore_index=True) target_pos_sch = TargetPosScheduler(api, "CZCE.MA609", time_table) while not target_pos_sch.is_finished(): api.wait_update() print(target_pos_sch.trades_df) average_trade_price = sum(target_pos_sch.trades_df['price'] * target_pos_sch.trades_df['volume']) / sum(target_pos_sch.trades_df['volume']) print("成交均价:", average_trade_price) api.close()此外,算法模块还提供独立的Twap类(tqsdk/algorithm/twap.py),可直接构造Twap(api, symbol, direction, offset, volume, duration, min_volume_each_order, max_volume_each_order, ...)完成一段时间内的拆单下单,并提供trades、average_trade_price、cancel()、is_finished()等接口;其内部同样基于InsertOrderUntilAllTradedTask,且同样支持support_open_min_volume。注意源码注释明确:Twap类不支持在回测中使用。
五、使用要点总结
综合源码与文档(doc/usage/targetpostask.rst、doc/advanced/targetpostask2.rst、doc/advanced/scheduler.rst),使用业务工具库时请牢记:
- 驱动主循环:
TargetPosTask/TargetPosScheduler的set_target_volume()/构造动作本身不直接下单,实际下单与撤单都在后续每次wait_update()中执行,设置目标后必须继续调用wait_update(); - 单例与参数不可变:每个账户下每个合约只能有一个
TargetPosTask实例且构造参数不可修改;更换参数需先cancel()再新建; - 勿混用下单方式:使用
TargetPosTask期间不要调用insert_order(),否则会导致报错或错误下单; - 大单拆分需成对设置:
min_volume与max_volume必须同时填写且满足max_volume >= min_volume > 0; - 多账户必须指定 account:
TqMultiAccount模式下所有工具类都必须显式传入account实例; - 价格函数不得返回 nan:自定义
price函数需自行对 nan 兜底,否则程序抛错; - 时间表约束:
time_table的interval可跨非交易时段但不可跨交易日,最后一项以目标手数达成为退出条件(price=None时立即退出); - 最小开仓手数合约:遇到
open_min_*_order_volume > 1的合约需设置support_open_min_volume=True,且调仓完成判断应改用|当前持仓 - 目标持仓| < open_min_limit_order_volume的宽松条件。
- 金融科技
【免费下载链接】tqsdk-python
天勤量化开发包, 期货量化, 实时行情/历史数据/实盘交易
相关推荐
天勤 tqsdk-python 下单与仓位工具实战指南:insert_order、cancel_order、TargetPosTask、TargetPosScheduler 与 Twap 的选型与用法
天勤 tqsdk python 下单与仓位工具实战指南:insert_order、cancel_order、TargetPosTask、TargetPosSch
金融科技TqSdk TargetPosTask 高级用法:cancel 与 is_finished 的实例生命周期管理实战
TqSdk TargetPosTask 高级用法:cancel 与 is_finished 的实例生命周期管理实战 导读 :TqSdk 的 TargetPosT
金融科技tqsdk-python TqSdk 模块参考指南:从 TqApi 核心接口到账户接入、指标与工具
tqsdk python TqSdk 模块参考指南:从 TqApi 核心接口到账户接入、指标与工具 本文围绕 doc/reference/index.rst h
金融科技
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考