11.6 日志与审计:每一笔交易必须可追溯
课前导读
学习目标
你将学会:用“黑匣子”思维记录每笔交易,让策略信号、风控结论、订单状态和成交结果都能被追溯。
适合谁读:已经理解订单生命周期和下单前风控,希望知道事故发生后如何复盘的学习者。
难度:advanced
预计用时:约 40 分钟
飞机有黑匣子。
医院有病历。
餐厅有小票。
实盘交易系统也必须有日志与审计记录。
当一笔交易亏损时,不能只说“策略不行”。
你要能回答:当时用的是什么数据?
信号为什么出现?
风控为什么放行?
订单有没有重复?
成交了多少?
是谁在什么时候改过参数?
日志与审计不是为了事后找人背锅。
它们是为了让系统从错误中学习,防止同类问题反复发生。
本节不涉及真实券商接口日志格式,也不提供任何可直接实盘连接的实现。
我们只学习通用的记录原则和字段设计。
知识正文
1. 类比:日志像交易系统的行车记录仪
开车时,行车记录仪不会替你踩刹车。
但事故发生后,它能告诉你红灯、车速、距离和时间。
交易日志也一样。
它不负责预测行情。
它负责把系统在关键时刻看到什么、想做什么、做了什么记录下来。
没有日志,亏损之后只能靠记忆。
而记忆会选择性遗忘。
有日志,复盘就能从情绪回到证据。
这对投资者、老师和开发者都很重要。
投资者需要知道钱为什么变少。
老师需要帮助学生区分策略问题、执行问题和纪律问题。
开发者需要定位程序是否按预期运行。
2. 从生活语言进入术语
日志:系统运行时留下的事件记录。
它像日记,但要求更精确、更有时间顺序。
审计:对日志和记录进行复核,确认每一步是否合规、可解释、可追溯。
追踪编号:把同一笔信号、订单、成交串起来的编号。
它像快递单号,让你知道不同记录属于同一件事。
决策原因:策略为什么要买、卖、撤或停止。
它不一定是长篇解释,但必须能还原规则依据。
数据版本:当时使用的行情、财务、因子或持仓快照版本。
同一个策略,在不同数据版本下可能给出不同结论。
信号版本:产生信号的策略规则或模型版本。
如果今天改了参数,必须知道新旧信号从哪里开始分叉。
订单状态日志:记录订单从生成到结束的每次状态变化。
它是上一节订单生命周期的证据链。
3. 交易系统的证据链
一笔交易至少会经过“数据、信号、风控、订单、成交、复盘”几个环节。
日志要把这些环节串成一条线。
sequenceDiagram
participant D as 数据快照
participant S as 策略信号
participant R as 风控检查
participant O as 订单管理
participant E as 成交回报
participant A as 审计复盘
D->>S: 提供行情和持仓版本
S->>R: 产生买卖意图和原因
R->>O: 返回通过或拒绝
O->>E: 跟踪提交和状态变化
E->>A: 记录成交数量和价格
O->>A: 提供订单生命周期
R->>A: 提供风控结论与原因
S->>A: 提供信号版本和参数这张图说明,审计不是最后才补写一段总结。
审计需要从一开始就收集证据。
如果策略信号没有编号,后面就很难知道订单来自哪条规则。
如果风控拒绝没有原因,开发者就无法优化检查表。
如果成交记录没有关联订单,投资者就无法判断滑点和执行质量。
4. A 股案例:亏损当天到底发生了什么
假设某策略在 10:15 买入一只 A 股。
下午收盘后,该股下跌,账户出现亏损。
新手可能会说:这只股票太差了。
专业老师会继续追问:买入信号是否符合策略规则?
投资者会追问:买入数量是否超过我的承受范围?
量化开发会追问:当时系统拿到的行情和持仓是不是最新?
如果日志完整,复盘可以这样展开。
先查看信号日志。
它显示策略版本为 v11.6-study,信号原因是“突破观察价且成交量放大”。
再查看数据版本。
它显示行情快照时间为 10:14:58,持仓快照时间为 10:14:59。
再查看风控日志。
它显示单票仓位从 8% 变为 12%,未超过 20% 上限。
再查看订单状态日志。
它显示订单先提交,随后部分成交 600 股,最后全部成交 1000 股。
再查看成交日志。
它显示成交均价高于信号触发价,存在一定滑点。
这样你就能区分:亏损主要来自策略判断、行情波动、执行滑点,还是系统错误。
如果没有日志,这些问题只能靠猜。
5. 日志字段:不要只写“成功”或“失败”
“成功”是一个危险词。
策略成功可能指产生信号。
风控成功可能指检查通过。
订单成功可能指提交成功。
交易成功可能指全部成交。
审计日志必须写清楚成功的是哪个环节。
下面是一张教学级字段表。
| 字段 | 示例含义 | 审计价值 |
|---|---|---|
| event_time | 事件发生时间 | 还原先后顺序 |
| trace_id | 贯穿信号到成交的追踪编号 | 串联证据链 |
| strategy_name | 策略名称 | 区分不同策略来源 |
| strategy_version | 策略版本 | 判断规则是否变更 |
| signal_id | 信号编号 | 定位具体决策 |
| signal_reason | 信号原因 | 解释为什么交易 |
| data_version | 行情或因子数据版本 | 判断是否使用过期数据 |
| position_snapshot_id | 持仓快照编号 | 还原下单前账户状态 |
| risk_result | 风控结论 | 判断是否按规则放行 |
| risk_reason | 风控原因 | 解释通过或拒绝依据 |
| order_intent_id | 订单意图编号 | 防止重复下单 |
| client_order_id | 内部订单编号 | 关联订单生命周期 |
| security_code | 证券代码 | 避免标的混淆 |
| side | 买入或卖出 | 明确交易方向 |
| target_qty | 目标数量 | 对比成交数量 |
| filled_qty | 已成交数量 | 还原真实持仓变化 |
| order_status | 订单状态 | 跟踪生成、提交、成交、撤单、失败 |
| avg_fill_price | 成交均价 | 分析滑点和执行质量 |
| operator | 系统或人工操作者 | 识别人工干预 |
| message | 简短说明 | 补充上下文 |
字段不需要一开始就做得很复杂。
但关键字段必须稳定。
否则今天的日志和明天的日志无法对比。
6. 决策原因:让交易从“感觉”变成“证据”
很多新手复盘时会写:当时感觉会涨。
这句话不能审计。
系统日志应该写得更具体。
例如:突破观察价。
例如:风险预算允许。
例如:止损线触发。
例如:黑名单命中而拒绝。
决策原因不一定证明决策正确。
但它能证明系统为什么这么做。
当同类亏损反复出现时,你就能统计原因。
是信号过于频繁?
是滑点太大?
是风控阈值太宽?
是数据延迟?
这些都需要从日志中找证据。
7. 数据版本和信号版本:防止复盘复不回去
量化系统最怕一种情况:今天复盘昨天的交易,却复不出昨天的信号。
原因可能是数据更新了。
也可能是策略参数改了。
还可能是因子计算逻辑修复了。
如果没有版本记录,你会误以为系统撒谎。
其实是你拿今天的尺子量昨天的决定。
所以日志要记录数据版本和信号版本。
数据版本告诉你当时系统看到了什么。
信号版本告诉你当时系统用什么规则判断。
参数版本告诉你阈值和开关是否变化。
这三者合在一起,才能支持可重复复盘。
8. 日志等级:不是所有信息都一样紧急
日志通常会分等级。
学习时可以先理解四类。
信息记录:正常流程,例如信号生成、风控通过。
提醒记录:需要关注但不一定停止,例如价格接近上限。
错误记录:某个动作失败,例如订单提交异常。
严重记录:可能影响资金安全,例如重复订单、风控开关异常、状态不一致。
不要把所有日志都当成错误。
否则真正的错误会淹没在噪音里。
也不要只记录错误。
否则流程正常时缺少证据链。
9. 审计关注的不是“谁对谁错”
好的审计会问四个问题。
第一,系统是否按当时的规则运行?
第二,当时的规则是否合理?
第三,数据、信号、风控、订单之间是否一致?
第四,下次如何降低同类风险?
审计的目标是改进系统。
如果审计只用于责备,人就会倾向于少记录。
如果审计用于学习,团队就会愿意把关键事实写清楚。
个人投资者也一样。
交易日志不是用来骂自己的。
它是用来让下一次决策更可控。
10. 隐私与安全:日志不能变成新风险
日志越完整,越要注意保护。
不要在日志中记录真实账号密码、访问令牌、短信验证码等敏感信息。
不要把包含真实账户隐私的日志随意上传公开平台。
不要为了方便排查,把安全边界写进明文记录。
教学项目里也应避免展示真实资金账号和真实交易通道细节。
可追溯不等于什么都公开。
专业日志追求的是必要、准确、可保护。
交互实验室
练习 1:订单日志字段表
请为一笔模拟订单填写下面的审计表。
| 字段 | 你的填写 | 提示 |
|---|---|---|
| trace_id | 用同一个编号串起信号、风控、订单、成交 | |
| event_time | 精确到你能复盘的时间粒度 | |
| strategy_name | 写清楚策略来源 | |
| strategy_version | 记录参数或规则版本 | |
| signal_id | 每次信号都应可定位 | |
| signal_reason | 不写“感觉”,写规则依据 | |
| data_version | 记录行情或数据快照来源版本 | |
| position_snapshot_id | 记录下单前持仓快照 | |
| risk_result | 通过、拒绝或需人工确认 | |
| risk_reason | 写明风控判断理由 | |
| order_intent_id | 用于识别重复订单意图 | |
| client_order_id | 用于关联订单状态变化 | |
| security_code | 教学示例可用虚构或公开代码 | |
| side | 买入或卖出 | |
| target_qty | 策略目标数量 | |
| filled_qty | 实际成交数量 | |
| order_status | 已生成、已提交、部分成交、全部成交、撤单或失败 | |
| avg_fill_price | 用于分析成交质量 | |
| operator | 系统、人工复核或人工撤单 | |
| message | 一句话补充上下文 |
练习 2:三分钟审计问答
拿一笔模拟交易,尝试回答以下问题。
- [ ] 我能找到这笔交易对应的信号编号吗?
- [ ] 我能说清它为什么被允许下单吗?
- [ ] 我能确认使用的数据不是过期快照吗?
- [ ] 我能看到订单从生成到结束的完整状态吗?
- [ ] 我能区分目标数量和实际成交数量吗?
- [ ] 我能判断是否存在重复下单风险吗?
- [ ] 我能解释最终亏损来自策略判断、执行滑点还是规则缺陷吗?
- [ ] 我能在不泄露敏感信息的前提下保存复盘证据吗?
如果有三个以上问题答不上来,说明日志设计还不够支持实盘复盘。
练习 3:给日志写一句合格说明
请比较下面两种写法。
| 写法 | 是否合格 | 原因 |
|---|---|---|
| 买入成功 | 不合格 | 不知道哪个环节成功,也没有原因 |
| 风控通过:单票仓位 12%,低于 20% 上限;资金余量充足 | 合格 | 有结论、有依据、可复核 |
| 下单失败 | 不合格 | 缺少失败位置和错误摘要 |
| 订单提交失败:数量不符合交易规则,已阻止进入交易通道 | 合格 | 明确失败原因和保护动作 |
从今天开始,把交易记录写成别人也能看懂的证据。
核心复盘
知识清单:
- [ ] 日志是交易系统的行车记录仪,审计是对证据链的复核。
- [ ] 每笔交易应能追溯到数据版本、信号版本、风控结论、订单状态和成交结果。
- [ ] “成功”和“失败”必须说明发生在哪个环节。
- [ ] 决策原因能让复盘从感觉回到规则和证据。
- [ ] 数据版本和信号版本能帮助你复现当时的判断环境。
- [ ] 日志等级要区分正常信息、提醒、错误和严重风险。
- [ ] 日志不能记录敏感凭证,也不能随意暴露真实账户隐私。
金句总结
没有日志的亏损只是情绪,有日志的亏损才可能变成经验。