本节摘要:实盘接入之后,每天真正保命的例行工作有两件:对账与熔断。本节先建立每日对账流程——从交易所拉取成交与持仓,与本地账本逐笔比对,差异按严重度分级处理,"对不上账"本身就是风险信号;然后定义异常熔断的自动触发条件(延迟飙升、重复订单、敞口超限)与人工熔断的决策矩阵;最后是合规边界:一张所在地的监管与税务自查清单,以及本书的一贯立场——本书不构成任何法律、税务或投资建议,边界问题请咨询当地持牌专业人士。本节结束,第 08 章的三个责任块(接入、通道、运维)合拢成一个可以长期运行的实盘底座。
本地账本记录"系统认为自己做了什么",交易所记录"世界实际发生了什么"。每日对账就是把两者放到一起:
每日对账流程(建议在交易日结束后固定时间执行) ┌────────────┐ 拉取成交/持仓 ┌────────────┐ │ 交易所 API │ ──────────────▶ │ 对账任务 │ └────────────┘ │ (celery 定时)│ ┌────────────┐ 读取本地账本 │ 逐笔配对 │ │ 本地数据库 │ ──────────────▶ │ 持仓比对 │ └────────────┘ └──────┬─────┘ ▼ 差异报告 ──▶ 分级处理(见下表)
对账内容分三层,任何一层对不上都要追:
| 层 | 比对内容 | 典型差异原因 |
|---|---|---|
| 成交层 | 逐笔成交:时间、价格、数量、方向 | 网络重试导致重复成交、部分成交未记账 |
| 持仓层 | 各标的持仓数量 | 成交层遗漏、转账/划转未建模 |
| 资金层 | 可用余额与权益 | 费用返还、利息、结算时差(券商 T+1) |
差异分级处理表(分级标准为作者建议,团队可书面约定更严的标准):
| 级别 | 判定 | 处理 | 时限 |
|---|---|---|---|
| 一级(信息级) | 手续费口径差、小额舍入 | 记录、次日复核 | 当日记录即可 |
| 二级(偏差级) | 成交缺失或重复、持仓不符 | 暂停该策略新单,人工逐笔核对 | 当日解决 |
| 三级(事故级) | 出现本地无记录的成交、资金异常变动 | 触发应急开关(第 10 章),全链路排查 | 立即 |
强调一个反直觉的纪律:对账的默认假设是"本地错了",而不是"交易所错了"。交易所的成交记录是最终事实源,本地账本是你的模型;模型与现实不符时,先修模型。同时,二级及以上差异发生后,该策略当日观察窗口数据作废——被污染的数据拿去判读(第 07 章的偏差指标)会得出错误结论。
对账本身可以用一段极简脚本表达骨架(示意逻辑,数据接口以实际部署为准):
# reconcile.py —— 每日对账最小实现(示意逻辑,字段以实际数据接口为准) def reconcile(local_fills, ex_fills, tol=1e-9): """local_fills/ex_fills: [{id, symbol, side, price, qty}],按成交编号配对""" local = {f["id"]: f for f in local_fills} remote = {f["id"]: f for f in ex_fills} diffs = [] for fid in sorted(set(local) | set(remote)): lf, ef = local.get(fid), remote.get(fid) if lf is None: diffs.append((fid, "本地缺失", 3)) # 世界有、模型没有:事故级 elif ef is None: diffs.append((fid, "交易所缺失", 2)) # 模型有、世界没有:偏差级 elif (abs(lf["price"] - ef["price"]) > tol * ef["price"] or abs(lf["qty"] - ef["qty"]) > tol * ef["qty"]): diffs.append((fid, "字段不符", 2)) return diffs def level(diffs): if any(d[2] == 3 for d in diffs): return "三级:触发应急开关,全链路排查" if diffs: return "二级:暂停该策略新单,人工逐笔核对" return "通过:记录归档,次日复核费差"
值得展开的有两点。其一,两个方向的缺失分级不同:交易所有一笔本地完全没有记录的成交,说明系统在"不知道自己交易"的状态下交易了——这正是分级表里的事故级判定;反过来本地多记了一笔(世界没有),更可能是重试路径的记账问题,按偏差级处理。其二,容差用相对值(乘以价格或数量本身)而不是绝对值:不同价位的标的,同一绝对误差的含义完全不同。
把二级差异的处置走成具体场景。某日对账报告:本地账本某标的多记了一笔成交——网络超时触发的重试,交易所只成交了一次,本地却记了两次。处置顺序:第一步,暂停该策略新单(改动最小、随时可逆);第二步,人工核对重试日志与交易所成交流水,确认世界只发生了一次;第三步,修正本地账本,并在差异报告记录根因;第四步,将该策略当日观察窗口数据标记作废;第五步,复盘时把"重试路径必须以交易所回执为记账依据"写进策略运行时的检查清单。整个流程的关键不是修那一笔数据,而是修"下次还会犯"的路径。
对账是事后审计,熔断是事中刹车。两类配合:
自动熔断(系统自己触发,条件示意,阈值按策略与通道特性设定):
| 触发条件 | 含义 | 动作 |
|---|---|---|
| 订单延迟持续超阈值 | 下单链路异常(第 11 章指标) | 停发新单,撤掉未成交挂单 |
| 短时间重复订单 | 重试逻辑失控 | 撤单并停策略 |
| 敞口超限 | 实际仓位越过 sizing/risk 约束 | 收缩到限额内,告警 |
| 对账三级差异 | 上一节的事故级 | 全停,等人工 |
人工熔断(你按下去,决策矩阵示意):
| 场景 | 动作 | 依据 |
|---|---|---|
| 数据源异常(行情乱码、缺口激增) | 停新单,保留持仓观察 | 错误数据上的决策不如不决策 |
| 决策门服务异常 | 按 9.2 节 fail 策略执行 | 事先想好,不要现场纠结 |
| 个人无法盯盘(出行、生病) | 降杠杆或停新单 | 运维连续性也是风控 |
| 市场极端事件 | 执行事先写好的预案 | 第 6.3 节"可放弃性"条款 |
应急开关的具体操作入口与开关名称以官方文档口径为准(多重应急开关,停新单/撤单类,见第 10.3 节展开),本节的职责是定"什么时候该按"。
本书不给任何法律意见,这里是一张自查清单,帮助你把该问的问题问全,答案请以所在辖区的官方发布与持牌专业人士的意见为准:
| 序 | 自查项 | 要问清的问题 |
|---|---|---|
| 1 | 准入资格 | 所在地是否允许个人/机构使用程序化交易此类工具 |
| 2 | 账户合规 | 交易所与券商账户的实名、KYC 状态是否完备 |
| 3 | 税务义务 | 交易损益如何申报、适用什么税目、记录保留几年 |
| 4 | 数据留存 | 监管或税务是否要求留存交易与决策记录 |
| 5 | 报告义务 | 达到什么规模或行为会触发额外报告义务 |
| 6 | 跨境问题 | 使用境外交易所/券商在所在地的法律地位 |
两个工程侧的配合点。其一,第 03 章数据层与本章对账记录天然构成交易留存的原始材料,但保留期限与格式要对照第 4 项要求核对。其二,QuantDinger 是自托管系统:合规责任在运营者身上,这是"数据不出门"的代价的另一面——自由与责任同源。
最后重申本章及全书的边界:本书内容仅限研究与教育用途,不构成任何投资、法律或税务建议;程序化交易可能违反你所在辖区的特定规则,接入真实资金前完成自查并咨询专业人士,风险自担。
| 频率 | 动作 |
|---|---|
| 每日 | 对账跑批并人工确认差异报告;浏览第 11 章关键指标 |
| 每周 | 复核偏差指标(第 07 章两指标在实盘初期的延续观察) |
| 每月 | 应急开关演练(第 10.3 节);key 与权限清单复查 |
| 每季 | key 轮换;合规清单重过一遍(示意节奏) |
这张表的隐含主张是:实盘运维是一组有节奏的例行工作,而不是"出事再救火"。节奏一旦形成,异常会自己浮出来——例行化是检测异常的先决条件。
| 现象 | 常见原因 | 第一动作 |
|---|---|---|
| 每天都有小额资金层差异 | 费用返还、利息、舍入口径 | 归入一级记录,连续数日复核是否收敛 |
| 对账任务本身没跑 | celery 队列积压或定时配置漂移 | 当系统异常处理:先看队列深度指标 |
| 成交全配对但持仓不符 | 比对口径漏了划转、转账类事件 | 把划转纳入持仓层比对范围 |
| 差异长期为零后突然放松警惕 | 例行化退化为盲签 | 差异报告的"零"也要有人真的看过生成过程 |
最后一行是运维的慢性病:对账连续一个月全绿之后,"确认差异报告"很容易变成无意识的点击。对策不是加流程,而是让确认动作带一点随机性——抽查某一天的报告,重跑一次对账脚本,比对两次结果是否一致。抽查成本一分钟,守住的是"全绿"这个信号本身的可信度。
到这里,真实订单已经可以发出、成交可以被核对、异常可以被刹停。还差最后一道工序:在订单发出之前,让一个理解语境的判断者再看一眼。下一章把 Jev 决策门装进下单链路——Decision Context V2 进去,typed Choice 出来,以及那个关键设计问题:决策服务挂了的时候,交易要不要继续。