Coverage And Gaps
ODTS 32 — 代码覆盖评估与行业知识盲区
这一篇不是”知识文档”,而是写给实习生/转行人看的”房间里的大象”——那些行业里人人都知道但没人写下来的东西。
一、覆盖评估:ODTS 系列到底写了多少
直接回答:写了约 15%-20%。
ODTS 系列目前 32 篇(含本文),覆盖了 OTC 衍生品业务和系统的核心框架——交易生命周期、产品类型、风险、估值、合规、角色地图。但如果按”一个 PM/BA 入职后应该知道的全部东西”算,还有大量空白。
每个知识盲区都有一个真实的业务成本。 下面几个故事,每一个都对应某个 ODTS 还没覆盖的领域——但都是真实发生过的损失事件。
故事 1:不知道 CCP 清算规则差异——多付了 200 万保证金
2019 年,ODTS 对接上海清算所(SHCH)的中央对手清算。团队以为”CCP 清算就是交易报过去,他们算保证金”。结果 SHCH 的初始保证金(IM)计算方式是组合层面的——不是逐笔算的。
开发按"逐笔计算 IM"设计系统 → 上线后:
→ 同一交易对手的 3 笔 TRS,每笔独立算 IM
→ 合计:800 万保证金
→ SHCH 实际收的(组合层面净额计算):600 万
→ 系统多算了 200 万
业务影响:
→ 运营按系统算的 800 万去备付保证金
→ 200 万资金被额外占用 × 1 个月
→ 资金成本(约 3% 年化):200万 × 3% / 12 = 5000 元/月
→ 更严重的是:运营始终不知道为什么系统算的保证金和 SHCH 对不上——每个月的对账都要花半天人工核对差异
→ 直到 4 个月后有人打电话问了 SHCH,才明白是组合计算
根本原因:
团队里没人真正理解"CCP 清算的 IM 计算方式"。
这是一个知识盲区——系统中没有这个领域的设计文档。
故事 2:不知道 CSA 的 Threshold 分交易对手类型——保证金通知全错了
ODTS 的保证金系统上线时,设计了一个全局的 Threshold 字段。运营配置了 500 万——意思是”未到 500 万不用追保”。结果:
券商自营的客户:Threshold 500 万 → 正常
银行客户:Threshold = 0(银行要求即时追保)→ 系统发错了
外资客户:Threshold = 1000 万(对方信用等级高)→ 运营手动改
上线第一天:
→ 某银行客户的浮动亏损 300 万,但系统没通知追保
(因为全局 Threshold 是 500 万,300 万 < 500 万 → 不发)
→ 客户自己打电话来问:"我们不是约好了 0 threshold 吗?"
→ 运营紧急手动发追保通知
→ 合规部门审查:"为什么这个客户的保证金通知延迟了 1 天?"
→ 解释:"系统上线初期参数配置错误"
业务成本:
→ 虽然没有实质损失,但合规风险事件留下了记录
→ 这个客户的下一个合作机会被合规部门要求"加强尽调"
→ 机会成本无法量化,但团队花了 2 周才能重新建立客户的信任
根本原因:
CSA(信用支持附件)的 Threshold 是按交易对手协商的——每个对手可能不同。
但系统中只设计了一个"全局"阈值。
这是"不知道业务领域规则"导致的系统设计缺陷。
故事 3:不知道利率互换(IRS)的计息日惯例——结算日期全部算错
ODTS 主要做权益衍生品(Equity Derivatives),团队对利率产品不熟。2021 年,一个客户要求做一笔简单的 IRS(利率互换)。开发按”天数 ÷ 365”算计息。
中国银行间市场的 IRS 计息惯例:
→ 人民币 IRS:ACT/365(实际天数/365)
→ 但实际上银行间市场用"实际天数 ÷ 365",但付息日遇到节假日顺延
→ 而固定 leg 和浮动 leg 的顺延规则不同:固定 leg 用"顺延"(Following),
浮动 leg 用"经调整的顺延"(Modified Following)
→ SHIBOR 3M 的计息基准是 ACT/360
系统第一次算出来的结算金额和对账方的差了 0.3%。
0.3% 听起来不大,但在 5 亿名义本金上 = 150 万。
这个例子完美说明”知识盲区的成本”: 不是系统 bug,不是代码写错,是团队根本没有”利率衍生品计息惯例”这个知识。开发按常识写,但衍生品市场的惯例不是常识。一个 ODTS 文档如果覆盖了 IRS 计息惯例,这个问题从一开始就不会出现。
如果这些故事说明了什么
ODTS 系列写了 31 篇,覆盖了约 15%-20% 的知识域。每篇都是因为某个团队踩过坑才写的——但坑还有很多没写完。这份文档不是学术论文,是踩坑记录集。每一篇没写的文档,背后都有人在某个下午因为不知道某个规则付了成本。
已覆盖的
| 领域 | 覆盖率 | 说明 |
|---|---|---|
| 产品基础(vanilla option, swap) | ~60% | 概念讲了,但实操细节不够 |
| 交易生命周期 | ~50% | 讲了流程,但没讲系统和数据的细节 |
| 风险类型 | ~40% | Gamma/Vega/CSA 讲了,WVaR/CCR 没深入 |
| 合规 | ~30% | 角色讲了,系统和数据部分没展开 |
| 角色地图 | ~70% | 每个角色一天怎么过讲得比较细 |
| 雪球/障碍期权 | ~80% | 新写的三篇比较深入 |
| 运营 | ~20% | 合同运营写了,但清算/对账/资金运营没写 |
没覆盖的重要领域
| 领域 | 为什么重要 |
|---|---|
| CCP 清算 (中央对手方) | 中国市场正在推场外衍生品集中清算,这是 2024-2025 的热点 |
| 交易对手信用风险 (CCR) | Basel III 的核心,场外衍生品的命门 |
| CSA 谈判实操 | Threshold/MTA/Haircut 在谈判桌上到底怎么谈,系统怎么配 |
| IR 互换 / 利率衍生品 | IRS、CCS、Basis Swap 在场外市场占半壁江山 |
| 信用衍生品 (CDS) | 中国版 CDS(CRM)在推,概念不同 |
| 估值调整 (XVA) | CVA/DVA/FVA — 前台和中台的核心战场 |
| 清算结算实操 | SWIFT/大额支付系统、CNAPS、场外和场内的结算差异 |
| 监管报送系统设计 | CSRC、SAC、中证报价的接口和数据格式 |
| 客户保证金计算 | IM (SIMM) vs VM, 不同 CSA 下的算法 |
| 主协议体系对比 | ISDA vs SAC vs NAFMII 的差异点 |
二、实习生不会知道的事(但 PM/BA 第二天就得懂)
2.1 业务惯例类
“为什么确认书上的到期日和实际结算日不是同一天?”
T(到期日)是合约最后一天,但结算通常在 T+1/T+2。因为需要时间确认最终的价格、计算应付款项、走资金审批。实习生经常以为到期日 = 结算日,然后在系统设计里把两个字段合并成一个。
“为什么有时候交易员说今天做个交易,但第二天才看到确认书?”
OTC 的交易确认流程是”先成交后确认为主”。电话/IM 上说定了一笔交易,交易员先在系统中录入,然后法务再去制作确认书。不是等确认书签好了才录入。这意味着系统必须支持”未确认”状态的交易——很多系统第一版没考虑到这个,导致确认书还没签回,运营已经在对账了。
“为什么名义本金和实际投资金额不一样?”
衍生品是杠杆的。投资者投入 1000 万(保证金),可能买了 1 个亿名义本金的雪球。这个”名义 vs 实际”的差异是刚入行的人最容易算错的地方。系统里这两个字段必须分开存,不能互相推导。
“什么叫 ‘第三方估值’?”
不是所有券商都用自己算的估值来做对账。市场上有很多第三方估值机构(如 Bloomberg Valuation Service, Markit, 中证估值),提供独立于交易双方的估值。双方都接受第三方的估值作为”仲裁基准”。做系统时,第三方估值接口可能是最重要的数据源之一。
2.2 系统设计类
“为什么系统中需要区分 ‘trade date’ 和 ‘effective date’?”
交易日在周一,但生效日在周三(等资金到位)。如果系统只存一个日期,运营就分不清”哪天成交的”和”哪天开始算 exposure”。
“为什么系统里要有 ‘version’ 字段?”
因为交易是可以修改的。不是改错了重来,而是有合法的生命周期事件(novation, amendment, correction)。每次修改都要留版本记录,而不是直接 UPDATE。
“为什么交易对手的 ID 不能只在 CRM 里存,每个系统一份?”
这是真实的教训。公司在交易系统里存了客户 A 的 ID = 1001,在保证金系统里存了同一家客户的 ID = ABC-001。对账时查了两天才发现是同一家。主数据管理是系统建设的第一课。
“为什么要把定价引擎独立出来?”
如果把定价逻辑写在交易系统里,每次 PnL 计算都会锁表。定价引擎的负载和交易系统的负载是不同量级的——EOD 批处理时定价引擎可能需要跑数万个估值,而交易系统只在营业时间办公。拆开是架构设计的常识,但很多系统第一版是耦合的。
“你说的 ‘定价引擎’ 可能不是一套代码”
前台用的定价引擎和中台用的可能是完全不同的两套。前台要快(毫秒级,参数可调),中台要稳(批处理,独立参数)。不同的模型实现、不同的数据源、不同的计算精度。同一个产品,前台算出来 99.7,中台算出来 100.2,然后 PC 团队要花一天追这 0.5 的差异。
2.3 数据和字段类
“为什么做字段设计时 ‘currency’ 不能只有一种?”
一笔跨境互换可能涉及两种货币——支付 CNY,收取 USD。系统中需要分别存 pay currency 和 receive currency。很多新手第一版只存了一个 currency 字段。
“为什么期权的 ‘quantity’ 不能只存 int?”
因为有些标的是指数(没有实物交割),有些是商品(可能用吨做单位),有些是汇率的多少倍。Quantity 的数据类型必须支持 decimal/numeric,不能是 int。
“为什么标的代码不是统一的?”
同一个中证 500,在 Wind 上代码是 “000905.SH”,在 Bloomberg 上是 “SHSZ500 Index”,在公司内部可能是 “CSI500”。一个字段存完外部代码还不够,还需要内部代码和映射表。
“什么是 ‘trade status’ 字段的合理取值范围?”
如果有人说”已确认”和”已生效”——那新手可能会觉得这是同一个意思。实际上可能的分法:Pending / Confirmed / Exercised / Expired / Terminated / Novated / Amended / Disputed。不同系统的值范围不同,但永远比你想的要多。
2.4 行业潜规则
“券商前台说的 ‘PnL’ 和财务说的 ‘PnL’ 不是一个数字”
前台的 PnL = 市场重估 - 成本,是”你今天赚了多少市场波动的钱”。财务的 PnL = 实际已实现收益 + 未实现损益,是”你在账上到底赚了多少钱”。两者之间的差异 = 估值调整 + 对冲成本 + 费用。新 PM 容易在需求里混用这两个概念。
“不要相信交易员说的 ‘系统很简单’”
交易员使用系统的方式和你设想的不一样。他的”简单需求”翻译过来可能是:
- “加一个字段” = 改数据库表结构 + 改 API + 改前端 + 改报表 + 改导出
- “改个参数” = 需要对数千笔存续交易重新估值
- “弄个报表” = 需要从 5 个系统拉数据做聚合
“监管要求的报送字段比你想象的多”
一个典型的中证报价日报表有 30+ 列。每列的数据可能需要从不同系统获取。你可能觉得 “报送数据 = 从交易系统导个 CSV”,实际是 ETL 管道从交易系统、风控系统、保证金系统、CRM 分别取数,做清洗、匹配、校验,才能生成报送文件。
“上线第一天的第一笔交易往往出问题”
新系统上线后的第一笔真实交易,一定会暴露你测试没覆盖到的问题——通常是边界条件、权限配置、或者某个外部接口没有真正连通。做 UAT 时一定要用真实数据跑一次完整的端到端流程。
三、读代码前必须知道的系统分层
任何 OTC 衍生品系统都可以按这个分层去理解。实习生拿到一个陌生系统的代码时,先问:这个模块在下面的哪一层?
┌─────────────────────────────────────┐
│ Front Office (前台) │
│ 交易录入、询价、报价、成交、PnL 试算 │
│ 性能要求:毫秒级响应 │
├─────────────────────────────────────┤
│ Middle Office (中台) │
│ 风险管理、估值校验、对冲、压力测试 │
│ 性能要求:秒级到分钟级 │
├─────────────────────────────────────┤
│ Back Office (后台) │
│ 清算结算、对账、资金划拨、监管报送 │
│ 性能要求:批处理(小时级) │
├─────────────────────────────────────┤
│ Operations (运营) │
│ 合同管理、客户服务、文档处理、归档 │
│ 性能要求:交互式 │
├─────────────────────────────────────┤
│ Enterprise / Shared (共享) │
│ 主数据(客户、标的)、权限、审计日志 │
│ 支撑所有上层 │
└─────────────────────────────────────┘
新手最容易犯的错误:用前台的需求去设计中台的表结构。比如”交易员要看实时 PnL”和”风控要做历史 PnL 归因”,虽然是同一个字段,但存储粒度、更新频率、一致性要求完全不同。
四、ODTS 系列当前的覆盖图
ODTS 01-04 ── 行业历史(4 篇)
ODTS 05 ──── 交易生命周期(1 篇)
ODTS 06-07 ── 代码地图 + 业务概念(2 篇)
ODTS 08-09 ── 定价与风险 + 迁移(2 篇)
ODTS 10 ──── 如何读代码(1 篇)
ODTS 11-12 ── 盈利模式 + 市场数据(2 篇)
ODTS 13-14 ── 客户准入 + 清算结算(2 篇)
ODTS 15 ──── 对冲工作流(1 篇)
ODTS 16-17 ── 保证金 + 确认(2 篇)
ODTS 18-19 ── EOD 批处理 + 监管报送(2 篇)
ODTS 20-21 ── 数据库 + 交易日时间线(2 篇)
ODTS 22-23 ── 生产事故 + 定价引擎架构(2 篇)
ODTS 24-25 ── 风控框架 + 系统架构总览(2 篇)
ODTS 26-27 ── 争议 + 生命周期事件(2 篇)
ODTS 28-31 ── 雪球 + 估值日合规 + 障碍期权 + 合同运营(4 篇)
ODTS 32 ──── 覆盖评估与知识盲区(本篇)
─────
总计:32 篇
绿色 = 已经比较深入;黄色 = 有概念但缺细节;红色 = 基本没有覆盖。
之后的生活:ODTS 33 — 交易全生命周期代码指南