前言
国内期货公司、机构内控或合规部门追问期货程序化交易时,常问:某年某月某日某时,你的程序为什么下了这一手、依据是什么、当时账户持仓多少、有没有被拒单。口头解释不够,需要长期保存、可检索的日志。期货程序化,指的是用天勤等工具把买卖决策写成 Python 程序自动执行;留痕,就是把程序每一步关键决定记下来,事后能拼成完整链条。
天勤量化程序里,事件散落在 while True 循环的 wait_update() 中:K 线 datetime 变了算信号、调用 set_target_volume、在后续 wait_update 里发单、get_trade 回报成交、委托 last_msg 报拒单原因。若你只 print(close),没有事件类型、没有 bar_datetime、没有 order_id,事后无法回答监管或内控的问题。下面给出最低字段清单、各字段从天勤哪里来、影子模式(只算信号不下单)如何记。不替代法律意见,只谈工程落地。
一、留痕要回答的五个问题
| 问题 | 日志应能回答 |
|---|---|
| 何时 | 日志时间、触发信号的 K 线时间 |
| 何合约 | 如 SHFE.rb2510 |
| 依据什么 | 哪根 bar、什么规则、目标几手 |
| 程序想做什么 | target、mode、version |
| 实际怎样 | 持仓 pos、委托状态、成交价、拒单原因 |
二、先弄清几个名词
| 字段/名称 | 是什么 | 在天勤里从哪来 |
|---|---|---|
ts |
日志写入时间 | 本机生成,建议北京时间 |
event |
事件类型 | 自定:signal / set_target / fill / reject / emergency |
symbol |
合约代码 | 策略使用的交易 symbol |
bar_datetime |
触发信号的 K 线业务时间 | kl.iloc[-2].datetime 或 tick 策略用 quote.datetime |
target |
目标净仓手数 | set_target_volume 之前的意图 |
pos |
实际净持仓 | get_position(symbol).pos |
order_id |
委托号 | get_order() 字典的 key |
order_status |
委托状态 | ALIVE 在途,FINISHED 结束 |
volume_left |
未成交手数 | order 对象 |
last_msg |
柜台说明 | 拒单原因常在此 |
trade_price |
成交价 | get_trade() |
mode |
运行环境 | sim / kq / live / shadow,团队自定 |
version |
策略发布版本 | 便于对应哪版代码 |
strategy_id |
多策略时的编号 | 团队自定 |
密码、TqAuth、资金户明文永不写入日志;账号若出现须打码。
三、事件示例(JSON 行)
信号产生时(每根信号 bar 最多一条):
python
log({
"event": "signal",
"ts": now_iso(),
"symbol": symbol,
"bar_datetime": str(kl.iloc[-2].datetime),
"target": target,
"pos": api.get_position(symbol).pos,
"mode": MODE,
"version": VERSION,
})
拒单或委托状态变化时:
python
log({
"event": "reject",
"order_id": order.order_id,
"order_status": order.status,
"last_msg": order.last_msg,
"volume_left": order.volume_left,
"symbol": order.symbol,
})
wait_update() 后读 order;在 is_changing(order, "status") 或 last_msg 时记录。
四、影子模式记什么
影子模式(只算信号、不下单)应用与 live 相同字段,mode=shadow,无委托时 order_id 可空。这样可与 live 日志按 bar_datetime 和 symbol 对比,验证新程序信号是否一致。
五、存储、轮转与对账
- 按日文件:
logs/strategy_20250301.jsonl,避免单文件无限增大。 - 日终用
get_trade()导出与日志按order_id、时间 join。 pos快照可与快期 APP 对照。- 上线验收清单应含「留痕字段齐全、模拟盘跑一周有样本」。
- 全程一个
TqApi,多策略用strategy_id区分。
留痕不依赖天勤单独产品模块,用 Python logging 或写文件即可;字段名与 objs.py 中 Order、Trade 属性一致,便于和期货公司沟通。
六、留痕时最容易漏什么
只打印收盘价,没有 event 和 bar_datetime;拒单不记 last_msg;不知道 target 与 pos 要分开记(意图 vs 柜台真相);多版本策略不记 version,出问题时无法对应代码。
总结
期货程序化监管留痕,是把每一次算信号、每一次调仓意图、每一次成交和拒单,用统一字段写成可检索的时间线。天勤的 bar_datetime、pos、order.status、last_msg、get_trade 正好对应这条链上的关键环节;配上 mode 与 version,就能回答「当时程序怎么想、柜台怎么回」。把最低字段清单写进策略交付文档、在 TqSim 或 TqKq 上先跑一周填满样本,团队在被追问某笔交易时,才能拿出日志复盘,而不是靠记忆拼凑。
FAQ
1)tick 策略 bar_datetime 填什么?
可用触发 tick 的 quote.datetime,或所属 K 线 bar 的时间,团队统一即可。
2)指标快照要不要记?
可记关键值(如 ma60),避免整表过大。
3)日志保留多久?
按团队合规要求;工程上做好按日轮转。
4)能否用 Excel?
可以导出分析,生产建议 JSONL 便于程序检索。
风险提示
以上内容用于日志留痕工程参考,不构成投资建议或法律意见。