☰
tqsdk-python 业务工具库实战指南:TqNotify、TargetPosTask 与 TargetPosScheduler 详解
2026/10/14 16:07:30 网站建设 项目流程
  • 金融科技

【免费下载链接】tqsdk-python

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

项目地址:https://gitcode.com/gh_mirrors/tq/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的核心工作流程:

  1. 构造时启动三个后台任务:主调仓任务_target_pos_task、行情时间记录任务_update_time_from_md,并注册任务结束回调;
  2. set_target_volume()只把目标手数发送到内部 channel_pos_chan,并不直接下单/撤单——实际动作在之后的每次wait_update()中执行,因此必须保证设置目标后主循环持续运行;
  3. 主调仓任务读取目标手数后,先判断当前是否处于可交易时间段(回测场景用_tqsdk_backtest的时间判断,实盘用 quote 行情时间判断),不在交易时段内则等待行情更新;
  4. 计算出与当前净持仓的差值delta_volume,按offset_priority的优先级顺序逐项调用_get_order得到 (报单开平标志、方向、手数),再交由InsertOrderUntilAllTradedTask执行;遇到逗号则等待此前所有报单任务全部成交;
  5. 每个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),使用业务工具库时请牢记:

  1. 驱动主循环:TargetPosTask/TargetPosScheduler的set_target_volume()/构造动作本身不直接下单,实际下单与撤单都在后续每次wait_update()中执行,设置目标后必须继续调用wait_update();
  2. 单例与参数不可变:每个账户下每个合约只能有一个TargetPosTask实例且构造参数不可修改;更换参数需先cancel()再新建;
  3. 勿混用下单方式:使用TargetPosTask期间不要调用insert_order(),否则会导致报错或错误下单;
  4. 大单拆分需成对设置:min_volume与max_volume必须同时填写且满足max_volume >= min_volume > 0;
  5. 多账户必须指定 account:TqMultiAccount模式下所有工具类都必须显式传入account实例;
  6. 价格函数不得返回 nan:自定义price函数需自行对 nan 兜底,否则程序抛错;
  7. 时间表约束:time_table的interval可跨非交易时段但不可跨交易日,最后一项以目标手数达成为退出条件(price=None时立即退出);
  8. 最小开仓手数合约:遇到open_min_*_order_volume > 1的合约需设置support_open_min_volume=True,且调仓完成判断应改用|当前持仓 - 目标持仓| < open_min_limit_order_volume的宽松条件。
  • 金融科技

【免费下载链接】tqsdk-python

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

项目地址:https://gitcode.com/gh_mirrors/tq/tqsdk-python
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询