期货程序化撤单改价后仓位乱了:cancel_order 与 TargetPosTask 协作

前言

国内期货程序化执行层,很多人用天勤 TargetPosTask 做趋势调仓:信号算出目标净持仓后 set_target_volume(n),task 在每次 api.wait_update() 里对价报单;行情跳动时,task 会先 cancel_order 撤掉自己的在场委托,再按新价重报。有人嫌追价慢,在同一合约上又手写 insert_order 改价,或在 task 撤单过程中再撤一次,结果 get_position().pos 短时间反复横跳,和信号层记忆对不上。

天勤文档明确:同一合约不要混用 TargetPosTask 与 insert_order。下面说明委托 status、volume_left 状态机、安全撤单顺序,以及只依赖 task 时改价已内置在哪里。

一、Order 状态字段

字段 含义
status ALIVE 在途,FINISHED 结束
volume_left 剩余未成交量
is_dead 是否确定不会再成交
is_error 是否错单
last_msg 柜台说明

撤单应针对 status == "ALIVE" 且 volume_left > 0 的委托。

二、TargetPosTask 内置改价逻辑

target_pos_task.py 文档:task 在每次下单后会根据行情计算最新价格,价格变化时先撤由该程序发出的在场委托,再按新价重报。因此多数场景不需要手写 cancel_order;改 price="ACTIVE" 或自定义 price 函数即可。

混用风险:

  • 你撤了 task 的单,下一帧 task 又报新单,逻辑难预测。
  • 你 insert_order 开仓,task 仍按旧 target 调仓,双倍持仓。
  • 单例 task 不知道你手写单的存在,pos 与 target 长期偏离。

三、若坚持手写撤单

仅建议在紧急停机或 task 已停用后:

python 复制代码
for oid, order in api.get_order().items():
    if order.instrument_id in SYMBOL and order.status == "ALIVE":
        api.cancel_order(oid)
while True:
    api.wait_update()
    if all(o.status == "FINISHED" for o in api.get_order().values()
           if o.instrument_id in SYMBOL):
        break
pos = api.get_position(SYMBOL).pos
# 再决定是否重建 TargetPosTask

撤单后必须多帧 wait_update 等到 FINISHED 或 volume_left==0,再读 pos。

四、部分成交后收尾

部分成交时 volume_left 大于 0。若策略放弃剩余意图,可 cancel_order 余单,并把 target 改为当前 pos,让 task 不再追剩余手数:

python 复制代码
task.set_target_volume(api.get_position(SYMBOL).pos)

这比继续追价更符合「成交多少算多少」的风控。

五、InsertOrderTask 边界

InsertOrderTask 是 task 内部类,一般策略不直接实例化。若用 InsertOrderUntilAllTradedTask 等扩展,同样遵守勿与 TargetPosTask 混用同一合约。

六、价变撤单重报时序

TargetPosTask 在 ACTIVE 模式下价格跳动会撤旧单重报。若你在外层又 cancel_order,可能出现「双撤」后短暂无单。日志里同时记 task 侧与手工侧撤单事件,复盘才能对齐时间线。

七、紧急停机顺序

  1. set_target_volume(pos) 冻结目标
  2. 撤所有 ALIVE
  3. wait_update 至 FINISHED
  4. 再 set_target_volume(0) 若需强平

跳步容易导致 task 又报新单。

八、模拟盘练撤单

在 TqSim 上挂 PASSIVE 远价单,练习 cancel_order 与读 volume_left 变化,熟悉 FINISHED 前后 pos 不变、仅委托消失的行为。

总结

撤单改价导致仓位乱,十有八九是 TargetPosTask 与手写 insert_order/cancel_order 在同一合约上抢控制权。天勤 task 已内置价变撤单重报,正常趋势策略应调 price 参数而不是外挂撤单。若紧急人工撤单,先停 task 意图(target 对齐 pos)、等委托 FINISHED、再决定是否重建 task,才能在程序化里保持仓位状态可解释。

FAQ

1)cancel_order 失败怎么办?

读 last_msg,可能已成交或已撤;以 get_order 为准。

2)task 能暂停吗?

没有 pause API;设 target=pos 等价暂停调仓。

3)多账户撤单要指定 account 吗?

TqMultiAccount 模式下 cancel_order 需对应 account 参数。

4)FAK 单还要撤吗?

FAK/IOC 类通常自动结束,少手动撤。


本文基于天勤 TqSdk 公开 API 整理,不构成投资建议。

相关推荐
前端精髓14 小时前
结构化输出with_structured_output(抽卡)
python·langchain
尹人入圣14 小时前
目前热门的IP驱动产业新场景新工具
网络·python·网络协议·tcp/ip
Nuanyt15 小时前
Agent 学习笔记(下篇三):上线工程、进阶选择与操作界面(Stage 7 / 7.5 / 8 + 延伸路线)
笔记·python·学习·memory·aiagent·harness
吴卫斌15 小时前
定投ETF实战指南(四):行业/主题ETF——定投的“进攻端“
开发语言·python·股票·量化
2601_9679873716 小时前
Python——入门级(定义功能def函数)
python·函数·可变参数·默认参数·关键字参数
专注仿真18 小时前
梯度提升类(XFBoost)算法详解与代码实例
开发语言·人工智能·python·算法·大模型训练·控制算法
外收内放18 小时前
Python基础语法练习题(75)
开发语言·python·学习
黑十19 小时前
PyTorch 报 “no CUDA GPUs are available“ 怎么办?3 步排查
服务器·网络·人工智能·pytorch·python
threelab19 小时前
开源图片去水印代码
python
taller_200021 小时前
【012】数据类型入门: Excel 数据到 Python 值的转换
python·excel·pie·py