前言
实盘里最耗时间的往往不是信号算错,而是 委托有、成交没有、持仓却对不上 这类状态问题。我见过策略日志写"已开多 2 手",get_position 却只有 1 手,最后发现是部分成交、重复报单、或平今平昨写错导致拒单。排查要有固定顺序,否则会在 print 里打转。
天勤 TqSdk 把委托、成交、持仓都挂在同一数据截面上,每次 wait_update 后可用 get_order、get_trade、get_position 拉齐。下面给一套从柜台回报到策略记忆的核对流程,并列出常见错位原因。
一、先定"以谁为准"
| 数据源 | 适合作为 |
|---|---|
get_trade |
已发生成交的真相 |
get_order |
在途与终态委托(含撤单、拒单) |
get_position |
交易所认可的持仓截面 |
| 策略自建变量 | 只能当缓存,不能当真相 |
一旦三者不一致,优先信 trade + position,回头改策略状态机,而不是强行改 position 理解。
二、推荐排查顺序(清单)
- 时间戳 :最后一次
wait_update是什么时候?若主循环卡住,看到的是旧截面。 - 活跃委托 :
orders = api.get_order(),筛status仍为未成、待撤的单。 - 当日成交 :
trades = api.get_trade(),按合约汇总成交量。 - 持仓 :
pos = api.get_position(symbol),看pos_long、pos_short、pos(净仓)。 - 策略日志 :同一时刻是否重复
insert_order或多次set_target_volume。 - 开平与方向 :上期所等区分平今/昨的合约,
offset写错会拒单但策略以为已平。
把 2~4 在一张表里打快照,比逐行 print 高效。
三、天勤字段级快速对照
委托 (get_order 返回的 order 对象,字段以当前版本文档为准):
status:是否已全成、撤单、拒单volume_orign/volume_left:原始手数与剩余insert_date_time:报单时间,用于和成交对齐
成交 (get_trade):
volume、price、direction、offset- 与 order 的
order_id关联(若字段存在)
持仓 (get_position):
pos_long、pos_short分列;净仓用pos- 浮动盈亏与
get_account权益分开看,避免把浮盈当可用资金
在 wait_update 后加:
python
api.wait_update()
if api.is_changing(pos, "pos_long") or api.is_changing(pos, "pos_short"):
print("持仓", symbol, pos.pos_long, pos.pos_short, pos.pos)
for oid, o in api.get_order().items():
if o.status == "ALIVE": # 以文档枚举为准
print("在途", oid, o.direction, o.offset, o.volume_left)
ALIVE 等状态字以你安装的 TqSdk 文档为准,不同版本命名可能略有差异。
四、五种高频错位原因
| 现象 | 常见原因 | 处理 |
|---|---|---|
| 委托有、无成交 | 限价太远、非交易时段、资金不足 | 看 quote 买卖盘与 get_account 可用 |
| 成交有、持仓不对 | 部分成交、多合约 symbol 写错 | 按 trade 汇总,核对合约代码 |
| 持仓对、策略记错 | 用全局变量记仓,未在成交后更新 | 以 position 为准重算或每帧同步 |
| 重复开仓 | 每 tick 都下单,未用 is_changing 限频 |
K 线策略配合 datetime 变化判断 |
| 平不掉 | 平今/平昨顺序、锁仓规则 | 检查 offset 与 TargetPosTask 的 offset_priority |
五、TargetPosTask 场景的额外检查
使用 TargetPosTask 时,下单撤单在 wait_update 里异步完成。若你手写日志在 set_target_volume 后立即打印 position,可能还没成交。
正确做法:等 is_changing(pos, ...) 或监听 task 的 trade_chan(文档中有成交通知 channel 可选参数)再记仓。
同一合约不要同时又用 insert_order,否则 task 内部状态与手动报单冲突,表现为委托列表混乱。
六、模拟与实盘核对差异
TqSim 进程内模拟与 TqKq 快期模拟账户不是同一套记录;团队对账要用 TqKq 或实盘账户,并在 APP 侧交叉验证。
回测结束用 BacktestFinished 捕获后导出成交统计,与实盘日志格式保持一致,方便横向对比。
总结
委托、成交、持仓对不上时,按 wait_update 是否新鲜 → 在途 order → trade 汇总 → position → 策略日志 顺序查,真相以 trade 和 position 为准。天勤在同一 API 截面提供三类对象,适合在 is_changing 触发时打结构化快照。
重点排查部分成交、重复报单、开平写错、TargetPosTask 后立即记仓、以及 TqSim 与 TqKq 混用。把核对脚本做成每日收盘后固定动作,比出问题时临时 grep 日志更省时间。
FAQ
1)get_order 空但策略下过单?
可能已全部成交或撤单完成;改查 get_trade 历史。也要确认是否连错账户实例(多账户模式要传 account 参数)。
2)净仓和多空对不上?
看是否同时有多空持仓(锁仓);有的策略看 pos,有的要看 pos_long/pos_short 分列。
3)回报延迟几秒算异常?
网络与交易所负载会导致延迟;若超过数十秒且无 wait_update,查主循环是否阻塞。
4)能否用 trade_log?
TqSim 等提供 trade_log 适合做模拟二次核对,实盘仍以实时 get_trade 为主。
风险提示
本文用于技术排查说明,不构成投资建议。