Contract Operations
ODTS 31 — 合同运营管理:上传、解析与归档
场外衍生品的合同运营是”无人在意但出了问题所有人都找你”的环节。对 PM/BA 来说,合同运营系统是连接法律文件和数据系统的桥梁——理解这座桥怎么建,是基本功。
一、为什么合同运营是一个系统问题
场外衍生品的每一笔交易背后都有一份或多份法律文件。这些文件在很多公司至今仍然以 PDF 附件 + 邮件的方式流转。“合同在邮件里”不是一句笑话。
合同运营系统的核心目标: 把非结构化的法律文件(PDF/Word)转化为结构化的数据(合约要素),存储并关联到交易系统。
运营人员每天处理什么
| 文件类型 | 来源 | 说明 |
|---|---|---|
| 主协议 (ISDA/SAC/NAFMII) | 客户签署 | 交易的法律框架,一份管所有交易 |
| 补充协议 (CSA/Schedule) | 客户签署 | 保证金、净额结算等条款 |
| 交易确认书 (Confirmation) | 每笔交易 | 具体交易的条款明细 |
| 修改/终止协议 (Amendment/Novation) | 事件触发 | 合同变更 |
| 补充文件 (Side Letter) | 特定约定 | 如费率调整、特殊条款 |
二、核心工作流
阶段 1:合同上传
上传是运营链条的起点。这不是一个简单的”选择文件→上传”:
| 步骤 | 说明 |
|---|---|
| 文件接收 | 通过邮件/网盘/API/内部系统多通道接收 |
| 格式校验 | 是否支持格式(PDF/Word/TIFF),文件是否损坏 |
| 命名标准化 | 统一命名规则:日期_交易对手_文件类型_V1.pdf |
| 元数据录入 | 手动或自动提取关键字段(交易对手、协议编号、日期) |
| 权限标记 | 谁可以查看此文件(风控/运营/前台/法务) |
| 版本标记 | 是否为首次上传还是替代已有文件 |
系统需要支持的典型场景:
场景 A:交易员把确认书邮件转发到 ops@firm.com → 系统自动解析邮件附件 → 提取交易对手+确认书编号 → 存入系统。
场景 B:法务在系统外签署了 CSA 补充协议 → 扫描后上传 → 手动录入修改的 Threshold/MTA 值 → 通知保证金系统更新参数。
阶段 2:解析
自动解析是最难也最有价值的部分。
解析错误导致的实际问题案例:
2019 年,ODTS 的解析引擎把一份雪球确认书的 knockInLevel 识别为了 knockOutLevel——两个字段在同一页,解析模板的坐标匹配偏移了约 2mm(客户 A 的确认书页边距和标准模板不同)。系统自动将解析结果推送到了交易系统。风控系统看到敲出价偏低,以为风险更小。直到第一次敲出事件触发时,系统计算出来的现金交割金额用了错误的障碍水平——差了约 50 万。
技术链:
→ 解析模板是 PDF 坐标固定匹配的(不是语义匹配)
→ 客户 A 的确认书页边距与默认模板差了约 2mm
→ 字段"KI: 75%"被坐标匹配读成了"KO: 75%"
→ 系统没有"KI < KO"的校验规则
→ 错误数据进入了交易系统的产品字段
业务教训:
解析器提取的字段在写入交易系统前,
应该通过领域规则校验(KI 必须 < KO、行权价必须小于等于当前价的 120% 等)。
一个简单的领域规则就能挡住这个错误——但系统没有做。
解析的三大挑战:
| 挑战 | 原因 | 影响 |
|---|---|---|
| 格式不统一 | 每家交易对手的确认书格式不同,甚至同一家对手的不同产品格式也不同 | 通用解析器几乎不可能,需要模板式解析 |
| 字段提取精度 | 同样的”Nominal Amount”,可能在文档顶部、中间或页脚 | 字段提取率通常只有 60%-80%,仍然需要人工复核 |
| 语言差异 | 中文合同 + 英文合同交叉,同一字段可能在任一语言版本中 | 解析器需要双语支持 |
解析流程(真实系统):
原始 PDF → OCR(图片型 PDF 需要) → 文本提取 → 模板匹配 → 字段提取 → 人工复核 → 结构化数据
↓
无法 OCR 的 → 人工录入(fallback)
常见的解析字段(交易确认书):
| 字段 | 示例值 | 解析难度 |
|---|---|---|
| 交易对手 | ABC Asset Management Ltd | 低(通常有固定位置) |
| 交易日 | 2024-06-15 | 低 |
| 到期日 | 2025-06-15 | 低 |
| 挂钩标的 | CSI 500 Index | 中(简称可能不同) |
| 名义本金 | CNY 10,000,000 | 中(货币符号可能缺) |
| 产品类型 | Autocallable Snowball | 高(各家用词不统一) |
| 敲入价/敲出价 | KI 75%, KO 103% | 高(可能藏在附录) |
| 票息 | 18% p.a. | 高(可能在条款页) |
阶段 3:校验与匹配
解析完成后,系统需要将数据与交易系统进行比对:
解析结果:交易对手=ABC, 名义本金=10,000,000
交易系统:交易对手=ABC, 名义本金=10,000,000
匹配结果:✓ 一致
解析结果:交易对手=ABC, 名义本金=10,000,000
交易系统:交易对手=ABC, 名义本金=9,800,000
匹配结果:✗ 差异(名义本金相差 200,000)
→ 自动标记差异,运营介入调查
匹配规则可以配置:
| 匹配类型 | 说明 | 动作 |
|---|---|---|
| 精确匹配 | 字段完全一致 | 自动通过 |
| 容差匹配 | 在允许误差范围内(如金额 ± 1%) | 自动通过 |
| 手动确认 | 解析字段置信度低于阈值 | 运营人工确认 |
阶段 4:存储与归档
| 需求 | 说明 |
|---|---|
| 不可篡改性 | 上传后的合同文件应标记为只读,任何修改生成新版本 |
| 版本控制 | 同一协议的多版本(如 CSA 多次修改)需可追溯 |
| 全文检索 | 支持按合同内容搜索(场景:法务想要找出所有含某个条款的合同) |
| 合规保存期 | 监管要求:从交易终止起至少保存 5-10 年 |
| 权限控制 | 哪些角色可以看到哪些合同(前台看到交易确认书但看不到法务内部讨论邮件) |
三、系统架构
┌──────────────┐
│ 多通道接收 │
│(邮件/API/上传)│
└──────┬───────┘
▼
┌───────────────────────────────────────────────────┐
│ 文件预处理 │
│ • 格式检测 • 病毒扫描 • 命名标准化 • 去重检查 │
└──────────────────────┬────────────────────────────┘
▼
┌───────────────────────────────────────────────────┐
│ 解析引擎 │
│ • OCR(图片PDF转文字) │
│ • 模板匹配(按交易对手+产品类型匹配模板) │
│ • 字段提取 + 置信度评分 │
│ • 自动或人工复核 │
└──────────────────────┬────────────────────────────┘
▼
┌───────────────────────────────────────────────────┐
│ 校验与关联 │
│ • 与交易系统数据匹配 │
│ • 差异告警 + 运营处理 │
│ • 关联到已有协议+交易 │
└──────────────────────┬────────────────────────────┘
▼
┌───────────────────────────────────────────────────┐
│ 存储与分发 │
│ • 加密存储(文件 + 元数据分离存储) │
│ • 按角色分发通知(新合同到达通知交易员/风控) │
│ • 全文索引 │
└───────────────────────────────────────────────────┘
四、PM/BA 常见问题
问:为什么不能依赖人工录入?
答:一个中型券商每天可能有 50-200 份新确认书流入。全部手工录入需要 3-5 名全职运营人员。解析系统 + 人工复核模式只需要 1 名。但如果解析率只有 60%,那人工复核的成本可能超过全人工——所以系统的解析精度是 ROI 计算的核心。
问:模板解析器的维护成本高吗?
答:非常非常高。每家交易对手的模板变了,解析器就需要更新。你的团队需要跟踪市场上 50+ 家交易对手的模板变化。一个实用的策略是:解析器先做一个通用字段提取(用 NLP/LLM),高置信度的自动通过,低置信度的转人工,而不是为每个对手维护精确模板。
问:文件只读不可改,但如果合同本身就签错了怎么办?
答:系统不应该允许”编辑”已上传的文件。正确做法是:上传更正版本(新版本号),原版本保留可查。系统需要支持在旧版本上添加注释:“此版本已被 2024-07-17 V2 版本替代,原因是行权价录入错误”。
五、和周边系统的交互
| 系统 | 合同运营系统提供 | 合同运营系统需要 |
|---|---|---|
| 交易系统 | 交易确认书的解析结果(交易要素) | 交易记录(用于匹配校验) |
| 保证金系统 | CSA 补充协议解析的 Threshold/MTA | 当前使用的保证金参数 |
| 风控系统 | 存量合同清单(哪些交易有纸面文件) | 风控审批状态 |
| CRM | 客户签署的协议版本 | 客户基本信息 |
| 监管报送 | 存量合同统计(报告用) | 报送要求(定期更新) |
| 归档系统 | 已到期的合同 | 合规保存期规则 |
六、一个实际的运营流程示例
券商 B 一天之内处理 100+ 份场外期权确认书。其合同运营系统的日终报告长这样:
日期:2024-07-17
接收文件总数:127
├─ 自动解析成功:89(70.1%)
├─ 需人工复核:31(24.4%)
│ ├─ 字段置信度低于 80%:23
│ ├─ 与交易系统不匹配:6
│ └─ 格式不识别:2
└─ 解析失败转人工录入:7(5.5%)
已确认并关联至交易系统:112(88.2%)
待处理:15
解析引擎版本:PARSER-V3.2.1
当日运行时间:08:15 → 09:47(含人工复核)
这个报告本身就是系统建设的重要度量指标。如果解析率从 70% 降到 60%,说明有大量新模板出现了,需要投入解析器维护。
实际系统集成 / Real System Integration
ODTS 的合同运营并非上述通用架构描述——它对接了两个具体系统:
文档生成:Doc Agent
Doc Agent 是 ODTS 的文档生成服务,通过 HTTP REST 将结构化的交易数据渲染为合同 PDF:
请求 (POST /doc-agent/generate):
{
"templateId": "confirm_snowball_v3",
"templateType": "CONFIRMATION",
"dataSource": {
"contractId": "SNB202507001",
"counterpartyName": "某某投资有限公司",
"notional": "10000000",
"knockInLevel": "75%",
"knockOutLevel": "103%",
"coupon": "18% p.a."
},
"outputFormat": "PDF"
}
响应:
{
"docId": "DOC20250716001",
"status": "SUCCESS",
"url": "/hcp/confirm/SNB202507001.pdf",
"pages": 12,
"generatedAt": "2025-07-16T10:30:00+08:00"
}
Doc Agent 支持的文档类型:
| 模板类型 | 用途 | 生成时机 |
|---|---|---|
CONFIRMATION | 交易确认书 | T+1 |
ISDA | ISDA 主协议/附件 | 客户入市 |
CSA | 信用支持附件 (Credit Support Annex) | 客户入市 |
AMENDMENT | 修改协议 | 事件触发 |
MARGIN_STATEMENT | 保证金对账单 | 日终/周终 |
文档存储:HCP 对象存储
所有生成的合同 PDF 通过 HCP (Hitachi Content Platform) 对象存储持久化:
| 操作 | 接口 | 说明 |
|---|---|---|
| 上传 | PUT /hcp/ns/{tenant}/{category}/{docId}.pdf | 直接 PUT 二进制 |
| 下载 | GET /hcp/ns/{tenant}/{category}/{docId}.pdf | 通过 HCP 网关 |
| 删除 | DELETE /hcp/ns/{tenant}/{category}/{docId}.pdf | 仅合规期限内可删除 |
| 查询 | GET /hcp/ns/{tenant}/?query={metadata} | 按元数据搜索 |
HCP 提供了文件级的高可用和版本控制。ODTS 在数据库中存储 HCP URL 而非文件二进制本身。
关键数据: java.util.HashMap<String, String> 用于存储合同文件的元数据(文件类型、HCP 路径、上传时间、操作人),这是系统中常见的”Map 即 schema”模式的体现。
HashMap 作为数据结构的真实成本:
这个 HashMap<String, String> 最初只有 5 个字段(文件名、类型、路径、时间、操作人)。两年后增长到了 20+ 个 key。新开发不知道哪些 key 是必填的、哪些是有意义的——他们只能从代码里找写入这个 HashMap 的地方,看写了什么 key。运营人员反馈”合同上传后有时看不到交易对手名称”——查了 3 天发现:交易对手字段写了两个不同 key(counterparty 和 counterpartyName),前端只读了一个。
业务成本:
→ 一个字段分裂成两个 key,运营看不到数据
→ 3 人×3 天排查 = 9 人天的成本
→ 问题修复后需要手动更新 200+ 条已有记录的 metadata
→ 运营在这 3 天内无法确认这 200+ 份合同属于哪个客户
根本原因:
不是技术团队的错——是"Map 即 schema"模式本身没有类型检查。
如果有人写了一篇内部 wiki 说明 key 的规范,这个问题不会出现。
但问题恰恰是:没人有动力写文档,因为 key 一直在增加。
确认书发送延迟的运营成本:
Doc Agent 生成 PDF 后,运营需要在当日通过邮件发给交易对手确认。如果 HCP 或 Doc Agent 在下午 4 点后出问题(系统每天下午 3 点开始批处理生成确认书),确认书就要等到次日才能发送。
场景:
下午 3:30 Doc Agent 超时(数据库连接池耗尽)
运营尝试重试 → 再次超时
DevOps 介入排查 → 发现连接池参数配置错误
修复后重跑 → 6:00 PM 所有确认书生成完成
运营开始发送邮件 → 7:30 PM 完成
真实影响:
交易对手在 T+0 收到确认书 → 当天可核对、当天可回复 → T+1 确认完成
交易对手在 T+1 收到确认书 → T+1 核对 → T+2 确认完成
一天的延迟 = 交易对手的信用额度多占用一天 = 该交易对手无法做新交易
→ 对做市商来说,信用额度是稀缺资源,每一分钟的占用都有机会成本
工作流总结
数据源 (eds-web-app 交易数据)
│
▼
Doc Agent (PDF 渲染)
│
▼
HCP (对象存储)
│
▼
ODTS 数据库 (记录 HCP URL + 元数据)
│
▼
运营人员 (通过 new-edsweb 查看/下载/发送)
下一阶段:ODTS 32 — 计划中