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

前言

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

天勤文档明确:同一合约不要混用 TargetPosTaskinsert_order。下面说明委托 statusvolume_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 等到 FINISHEDvolume_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 整理,不构成投资建议。

相关推荐
CTA终结者1 小时前
期货量化合约代码写错:天勤 symbol 格式与 silent 订阅坑
python·区块链
如烟花的信页1 小时前
加速乐cookie逆向分析
javascript·爬虫·python·js逆向
装不满的克莱因瓶1 小时前
PyTorch 与它的自动微分工具:Autograd
人工智能·pytorch·python·深度学习·神经网络·机器学习·ai
cd988802 小时前
2026年,电销机器人哪家技术强?
python
weixin199701080162 小时前
[特殊字符] 1688开放平台API Sign签名算法详解(Java / Python / PHP 实现)
java·python·算法
TickDB2 小时前
Python 调用实时行情 API:ticker 返回成功后,如何校验字段再入库或展示
python·websocket·行情数据 api
AC赳赳老秦2 小时前
OpenClaw 助力技术面试:自动生成面试题、模拟面试、整理面试知识点
开发语言·python·面试·职场和发展·自动化·deepseek·openclaw
Hali_Botebie2 小时前
PyTorch 2.x核心变革torch.compile(),Triton 是其中最重要的 kernel 生成方式之一
人工智能·pytorch·python
我登哥MVP2 小时前
VS Code 安装 Claude Code 并接入 DeepSeek V4 Model
人工智能·python·node.js·agent·codex·deepseek·claude code