Learning
VOL. VII · NO. 82 · OTC Derivatives · 19 JUL 2026

Trade Lifecycle Code Map

OTC 衍生品 · 19 JUL 2026 · 19 min read · 2,489 words
· · ·

ODTS-33: Trade Lifecycle Code Map(基于 CICC 真实代码库)

目标读者:需要阅读 CICC OTC 衍生品系统代码的 BA/PM

前置阅读:ODTS-01 产品体系, ODTS-31 合同运营

本文定位:这是一份代码地图,不是功能列表。它回答的是”这段代码在哪个文件、哪个类里、表长什么样”。


1. 什么是代码地图

CICC(中金公司)的 OTC 衍生品系统是一个 10+ 年演进的庞然大物。两个世代并存:

  • odts1(一代):Struts2 + Spring Boot 混合,单体应用
  • odyssey(二代):Spring Boot 微服务 + Vue.js,逐步替代一代

对于一个 BA/PM 来说,最大的障碍不是业务概念——而是你知道业务上应该有个逻辑,但不知道那坨逻辑在代码的哪个角落里。

本文按交易生命周期组织代码路径,让你能快速定位。


2. 系统顶层架构

┌─────────────────────────────────────────────────────────────┐
│                    FRONTEND (Vue.js)                        │
│  ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌─────────┐  │
│  │ eds-rm-web │ │ odts-      │ │ odyssey-   │ │ odts-   │  │
│  │ (Risk Mgt) │ │ option-web │ │ swap-web   │ │linear-web│ │
│  └──────┬─────┘ └─────┬──────┘ └─────┬──────┘ └────┬────┘  │
└─────────┼──────────────┼──────────────┼──────────────┼───────┘
          │              │              │              │
          ▼              ▼              ▼              ▼
┌─────────────────────────────────────────────────────────────┐
│               BACKEND (Java, 多个独立进程)                    │
│  ┌────────────────────────────────────────────────────────┐  │
│  │  eds-web-app (主后端, ~4000 Java 文件)                 │  │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐  │  │
│  │  │ edsBoot/ │ │ action/  │ │ service/ │ │sblbooking│  │  │
│  │  │(Spring)  │ │(Struts2) │ │(Spring)  │ │ (SBL)    │  │  │
│  │  └──────────┘ └──────────┘ └──────────┘ └──────────┘  │  │
│  └────────────────────────────────────────────────────────┘  │
│  ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐      │
│  │ hedging-as  │ │ eds-price-   │ │ sac-report       │      │
│  │ (对冲+风控)  │ │ server       │ │ (监管报送)        │      │
│  └─────────────┘ └──────────────┘ └──────────────────┘      │
│  ┌─────────────┐                                             │
│  │ eva-master  │ (Python, Prometheus 监控 + Oracle SQL)      │
│  └─────────────┘                                             │
└─────────────────────────────────────────────────────────────┘
          │              │              │              │
          ▼              ▼              ▼              ▼
┌─────────────────────────────────────────────────────────────┐
│               DATA + MESSAGING                              │
│  Oracle DB │ ActiveMQ │ Kafka │ Redis │ DolphinDB │ Protobuf│
└─────────────────────────────────────────────────────────────┘

二代微服务(~/odyssey/):正在逐步从 odts1 迁移出来

  • odyssey-option-web / odyssey-swap-web / odts-linear-web:Vue 前端
  • odyssey-quotation-service:二代报价服务
  • odyssey-cash-manager-service:二代资金管理
  • odyssey-report-processing-service:二代报表处理
  • odyssey-internal-gateway:二代网关
  • ciccchecker:合规检查

3. 核心数据模型

理解 CICC 系统的关键在于理解它的字段编码体系

3.1 EdsSubContract——你的数据入口

这是整个系统最核心的数据模型。文件路径:

~/odts1/eds-web-app/src/com/cicc/action/dynamic/model/EdsSubContractDBModel.java

它有 80+ 个字段,每个业务字段都带一个 E编码。这个编码对应数据字典 EDS_ELEMENTDICT 中的一条记录。例如:

字段名编码含义示例值
contractname_e000024E000024合约名称”XQQ 1M TRS”
contractstatus_e000025E000025合约状态NEW / OPEN / EXPIRED
tradeaccount_e000026E000026交易账户 ID”TA001234”
product_e000027E000027产品类型”2”=TRS, “4”=RISKY, “5”=RHEG
bsflag_e000029E000029买卖方向B=Buy, S=Sell
tradedate_e000034E000034交易日20250115
observationenddate_e000035E000035观察结束日/到期日20260115
initquantity_e000113E000113期初数量/名义本金1000000
bookdate_e000114E000114记账日20250115
settledate_e000169E000169结算日20250117

TRS 专属字段(E02 开头):

字段名编码含义
needpricingpbtrs_e020001E020001是否需要定价
pricepbtrs_e020002E020002定价
currencypbtrs_e020003E020003币种
initnppbtrs_e020008E020008期初名义本金
interestindexpbtrs_e020010E020010利率指数 (如 SHIBOR)
interestindexratepbtrs_e020011E020011利率费率
interestbpspbtrs_e020012E020012利率基点 (BPS)
initialmarginrtpbtrs_e020014E020014初始保证金率
mtcmarginratio1pbtrs_e020015E020015MTC 保证金率 1
mtcmarginratio2pbtrs_e020016E020016MTC 保证金率 2

标的物字段

字段名编码含义
slunderlyingid_e010001E010001标的物 ID (股票代码)
leftquantity_e010007E010007剩余数量
accrualdays_e010010E010010计息天数

解约相关

字段名含义
unwindtext_e020020解约文本
unwindintrule_e020021解约利息规则
unwindhedgetool_e020022解约对冲工具
ptya_unwind_comm_inA方解约佣金(入)
ptya_unwind_comm_outA方解约佣金(出)
ptyb_unwind_comm_inB方解约佣金(入)

产品类型映射(代码中硬编码):

product_e000027 = "2" → contractType = "TRS"
product_e000027 = "4" → contractType = "RISKY"
product_e000027 = "5" → contractType = "RISKY_HEDGE"

3.2 为什么用 EAV——flexible schema

CICC 不把合约字段展开成表列,而是用 EAV 模式:

EDS_CONTRACTELEMENTVALUEEOD 表:
  contractId | elementId | elementValue | isModifiable | isVisible
  ---------------------------------------------------------------
  C001       | E000024   | "XQQ TRS"   | Y            | Y
  C001       | E000025   | "OPEN"      | N            | Y
  C001       | E000027   | "2"         | N            | Y

代码中的 Java 模型 EdsSubContractDBModel 则是这个 EAV 表的一行宽表映射——把 80+ 个 element 拉平成 Java 字段。两种方式都存在:

  • action/dynamic/model/EdsContractContext/EdsContract.java + EdsContractElementValue.java:EAV 方式,用于模板渲染
  • action/dynamic/model/EdsSubContractDBModel.java:宽表快照,用于业务逻辑

这就是为什么你会看到有些代码读 EDS_CONTRACTELEMENTVALUEEOD 表、有些代码直接用 EdsSubContractDBModel

3.3 EdsSubRequest——合约事件请求

~/odts1/eds-web-app/src/com/cicc/action/dynamic/model/EdsSubRequestDBModel.java

每个合约可以关联多个”事件请求”,由 contractEventId 区分:

  • CE202:一种事件类型(如敲出/分红)
  • CE203:另一种事件类型

一个 EdsSubContractDBModel 持有一个 requestMap

HashMap<String, HashMap<String, EdsSubRequestDBModel>> requestMap
//  key=contractEventId → key=hedgetradeid → request

请求字段包括:

  • quantitydelta_e010101:数量变化(对冲交易量)
  • initialmargin_e020401:初始保证金变化
  • commission_e020402:佣金
  • exchangefee_e020403:交易所费用
  • dividendamt_e020411:分红金额
  • fixingrate_e020415:Fixing 利率
  • hedgetradeid_e020417:关联的对冲交易 ID
  • realizedcommcalccy / realizedcommsettccy:已实现佣金
  • realizedannualfeecalccy / realizedannualfeesettccy:已实现年费

3.4 Contract(旧模型)

~/odts1/eds-web-app/src/com/cicc/action/contract/model/Contract.java

这是一个较早的合约模型,与 EdsSubContractDBModel两套体系,存在于不同历史阶段。它的字段不带 E 编码,命名风格也不同:

tradeDate, type, clientDentifier, underlyingFullTicker, stkid, exchid,
quantity, price, amount, feeFlag, initQuantity, PNL, isDividendStock,
status, contractName, templateId, productId, bsFlag, leftQuantity, ...

注意这个模型有 PNL 字段(盈亏),在 EdsSubContractDBModel 中不存在。这个模型中的 underlyingIdstkid 可以关联到 EdsSubContract 中的 slunderlyingid_e010001


4. 核心产品类型的代码路径

定价引擎中有 30+ 种结构类型,以下是最核心的几种及对应的代码位置。

TRS(Total Return Swap, productId=2)

系统中最核心的产品线。代码路径:

活动代码位置
TRS 定价~/odts1/eds-price-server/src/com/cicc/priceserver/pricingengine/PricingEngine.java 中 productId=“2” 的 switch branch
TRS 合约创建edsBoot/controller/ContractController.java + PbTrsContractGroupController.java
TRS 保证金~hedging-as/src/com/cicc/pricingengine/QuotationMarginServiceImpl.java
TRS 日终清算eds-web-app/src/com/cicc/sblbooking/service/InterestEodService.java
TRS 利率计算通过 interestindexpbtrs_e020010 (SHIBOR/FR007) + interestbpspbtrs_e020012 (基点)
TRS 合约组pbtrscontractgroup_e020024 字段关联到 PbTrsContractGroup 模型
AB股交易action/dynamic/model/newAB/ 下的 ABTradeBean, NewABContractBean

典型字段值:

product_e000027 = "2"
contractType = "TRS"
interestindexpbtrs_e020010 = "SHIBOR 3M" 或 "FR007"
interestbpspbtrs_e020012 = "100" (即 +1.00%)

Risky Structure(雪球, productId=4)

活动代码位置
雪球定价PricingEngine → 结构类型 switch: RISKY, ACPS, ZCC, BR, DSF, SF, PPDSF 等
敲出事件action/equityevents/ + EdsSubRequestDBModel 中的 CE202/CE203 事件
观察日逻辑action/dynamic/model/ 下的观察日期逻辑

在 PricingEngine 中支持的结构类型列表(所有能在代码中看到的):

VAN(普通香草), ACPS(自动赎回), CPS, ZCC(雪球), BR(保本), 
RISKREVESAL, BUTTERFLY, STD(标准), DIG(二元), SF, DSF,
STEP, STEP2, IPP, SPP, SPPF, RISKY(雪球), IPKSFSF, IPKVANSF,
LOAN, TRS, ETRS, PPSF, PPDSF, NPP, BR3, FCPS, CLQ(经典),
RA, REP, OT, ASIAN(亚式), ESF, CCSF, DCCS, STP, IDP, DCCSP

这些类型对应 PricingEngine 中的 StructuredProduct 子类:

  • VANValue → 香草
  • SPPValue → 雪球
  • TRSValue → TRS

RHEG(Range Hedge, productId=5)

product_e000027 = "5"
contractType = "RISKY_HEDGE"

5. EOD(End of Day)批处理

EDS 系统有大量的 EOD 批处理任务,集中在 edsBoot/ 包中:

~/odts1/eds-web-app/src/com/cicc/edsBoot/
├── consumer/         → ActiveMQ/Kafka 消费者(异步 EOD 任务)
│   ├── book/         → 簿记消费者
│   ├── order/        → 订单消费者 (含 PbContractTypeEnum)
│   └── trade/        → 交易消费者
├── controller/       → REST API(EDS 的主要后端入口)
│   ├── contract/     → 合约相关
│   ├── risk/         → 风控(含 OptiverFileUploadController)
│   ├── newab/        → A/B 股交易
│   ├── etf/          → ETF
│   └── equityevents/ → 权益事件
├── service/
│   ├── OptionExecutionService.java     → 期权行权
│   ├── OptionSubscribeService.java     → 期权认购
│   ├── HedgeTradeService.java          → 对冲交易生成
│   ├── PreBookService.java             → 预记账
│   ├── ClosePriceService.java          → 收盘价
│   ├── RiskService.java                → 风控规则
│   └── margin/                         → 保证金服务
├── model/
│   ├── optionExecution/
│   ├── profit/
│   └── margin/enums/ProductType.java
├── mapper/          → MyBatis Mapper
└── resource/mapper/ → XML Mapper

5.1 利息 EOD(InterestEodService)

~/odts1/eds-web-app/src/com/cicc/sblbooking/service/InterestEodService.java

处理 TRS 产品的利息日终。方法:

方法用途
dealInterestEod()主利息 EOD 处理
dealPbriskEod()PB 风险 EOD
dealCatsEod()CATS EOD
dealPbriskEodByReckTimes()按清算次数处理 PB 风险

清算次数(reckTimes)是 EDS 的一个核心概念——一笔业务可能分多次清算。

5.2 清算(Reckoning)

~/odts1/eds-web-app/src/com/cicc/action/dynamic/reckoning/
~/odts1/eds-web-app/src/com/cicc/reckoning/
~/odts1/eds-web-app/src/com/cicc/edsBoot/controller/ReckoningController.java
  • EdsReckoningUtils.java:清算工具类(含 getPrevSysTradeDate
  • 清算流程包括:预记账 → 正式清算 → 结算

5.3 Optiver 集成

~/odts1/eds-web-app/src/com/cicc/edsBoot/controller/risk/OptiverFileUploadController.java
~/odts1/eds-web-app/src/com/cicc/edsBoot/service/OptiverFileUploadServiceImpl.java

Optiver 是一家知名的全球做市商/高频交易公司。CICC 与 Optiver 之间通过 SFTP 批量交换文件:

接口用途
/Optiver/Valuation/upload上传估值文件给 Optiver
/Optiver/riskMargin/upload上传风控保证金文件
/Optiver/limitUnderlying/upload上传限售股清单
/Optiver/upload/file上传清算文件
/Optiver/upload/reckoningFile上传 CSDC(中登公司)清算文件

这意味着 CICC 可能与 Optiver 有 OTC 衍生品交易对手关系,通过批处理文件交换估值和风控数据。


6. 对冲引擎(hedging-as)

~/odts1/hedging-as/

这是一个独立的 Java 应用服务器,启动入口 HedgingAS.java。启动顺序揭示了它的模块结构:

1. QuotationService        → 报价服务
2. GatewaySessionManager   → 网关会话(Protobuf RPC)
3. HedgingRpcService       → 对冲 RPC 服务
4. BookingService          → 簿记服务
5. ActiveMQ (HedgingEntry) → 消息队列消费者
6. QuotationInfoCache      → 行情缓存
7. PythonApplicationManager → Python 估值集成
8. ContractStateMachineManager → 合约状态机
9. QuotationMarginService  → 报价保证金
10. UnderlyingValuePool    → 标的值池
11. JFinal Web Server      → 嵌入式 HTTP 服务

核心组件:

模块用途
QuotationService实时报价生成
HedgingRpcService对冲交易 RPC 接口
ContractStateMachineManager合约状态转换(NEW→OPEN→EXPIRED…)
QuotationMarginServiceImpl保证金计算
PythonApplicationManager调用 Python 估值模型
UnderlyingValuePool基础标的值缓存
QuotationInfoCache行情缓存
BaseRiskCheckControl基础风控检查

合约状态(来自 ContractStatus.java):

PRETRADE → NEW → OPEN → EXPIRED

7. 定价引擎(eds-price-server)

~/odts1/eds-price-server/src/com/cicc/priceserver/
├── pricingengine/
│   ├── PricingEngine.java       → 主入口
│   └── StructuredProduct/       → 各种产品定价模型
├── gpricingengine/pricing/
│   └── GPricingEngine.java      → Greeks 计算引擎
├── webservice/                  → SOAP Web 服务
└── cache/                        → 缓存

PricingEngine.java 有两个用途:

  1. 定价(Pricing):实时报价,返回 Premium
  2. 估值(Valuation):盘中/盘后计算 NPV

输出指标(Greeks):

OptionNPV | DeltaNPV | GammaNPV | ThetaNPV | VegaNPV | RhoNPV | PremiumNPV | TotalNPV

定价引擎在 hedging-as 中有一个 SOAP Web Service 接口:

Endpoint: http://10.110.224.205:9091/PricingEngine?wsdl
用途:IRS curve pricing, 摊销 IRS pricing

8. 监管报送(sac-report)

~/odts1/sac-report/
├── src/SacReportAs.java     → 主入口
├── src/com/cicc/report/
│   ├── SacReportUtil.java
│   └── ...
└── ...

启动入口 SacReportAs.java 启动一个独立的 Process,包含:

  • SacReportUtil.sacReportInitStart():初始化报送引擎
  • 支持 SAC/ISDA/NAFMII 三大协议体系的报告格式
  • 前端 ProtoBuf 服务器(ProtoBufServerForFrontAccess)用于前台访问
  • 20 线程池处理 ACP 消息
  • 嵌入式 Spring Boot Web

代码路径 action/web/dao/sacreport/model/ 下包含三个子目录:

  • module/sac/:SAC 模板(中国证券业协会)
  • module/isda/:ISDA 模板(国际)
  • module/nafmii/:NAFMII 模板(中国银行间市场交易商协会)

9. EVA 监控平台(Python)

~/odts1/eva-master/
├── run.py            → Prometheus metrics server (port 5000)
├── service/
│   ├── odts.py       → 核心 Oracle SQL 查询
│   ├── health.py     → 健康检查
│   └── git.py        → Git 信息
├── lib/
│   ├── routing.py
│   └── singlepattern.py
└── config/

EVA 监控的是运营和业务状态,不是技术监控。它的 odts.py 中的 Oracle SQL 查询回答了这些问题:

查询含义
Notional by currency各币种名义本金
Counterparty count history交易对手数量变化
Trade account stats交易账户统计
Primary & secondary reckoning progress一次/二次清算进度
Linear PB totals & trends线性 PB 总量和趋势
Non-linear option structure breakdown期权结构分类统计
Valuation table generation monitoring估值表生成监控
Event processing dashboard事件处理仪表盘
Business operation flow业务操作流程

10. 前端架构

一代前端(odts1)

eds-rm-web(风险管理):

src/views/
├── risk-management/    → 风控 (control, counterparty, var, rate, sbl, template...)
├── margin-manage/      → 保证金 (margin-call, pre-margin-call, control-detail...)
├── hedge-monitor/      → 对冲监控
├── stress-testing/     → 压力测试
└── home/               → 仪表盘

odts-option-web(期权交易):只有 home/ 目录(可能是更老的应用)

二代前端(odyssey)

odts-linear-web(线性产品,最完整的二代前端,27 个模块):

src/views/pages/
├── trade/              → 交易管理 (HedgeTrade, RealTimeTrades)
├── contract/           → 合约管理
├── reckoning/          → 清算
├── riskMgt/            → 风险管理
├── eod/                → 日终
├── ValuationMgt/       → 估值管理
├── account/            → 账户管理
├── positon/            → 持仓(注意拼写是 positon 不是 position)
├── recon/              → 对账
├── dma/                → 直接市场接入
├── pks/                → PKS 集成
├── equity/             → 权益事件
├── gma/                → GMA
├── dayTrading/         → 日内交易
├── reportMgt/          → 报告管理
├── sbl/                → 证券借贷
├── pbContractFile/     → PB 合约文件
├── underlying/         → 标的物管理
└── idx/                → 指数

odyssey-option-web:期权(新,只有 home) odyssey-swap-web:互换(新,交易+合约+help+user)


11. 生命周期到代码的映射

阶段                     一代代码                               二代代码
────────────────────────────────────────────────────────────────────────────────────
定价/报价                eds-price-server/                     quotation-service
                        hedging-as/QuotationService

交易录入                edsBoot/controller/ContractController    odts-linear-web/trade/
                        edsBoot/controller/newab/NewABTradeController

合约创建                action/contract/model/Contract.java     odts-linear-web/contract/
                        action/dynamic/model/EdsSubContractDBModel.java

事件管理                EdsSubRequestDBModel (CE202/CE203)     odts-linear-web/equity/
                        action/equityevents/

盘中对冲                hedging-as/HedgingRpcService
                        edsBoot/service/HedgeTradeService

估值/Pricing           eds-price-server/PricingEngine          odts-linear-web/ValuationMgt/
                        hedging-as/PythonApplicationManager

保证金                  hedging-as/QuotationMarginService      odts-linear-web/riskMgt/
                        eds-rm-web/margin-manage/

日终(EOD)              sblbooking/InterestEodService           odts-linear-web/eod/
                        edsBoot/consumer/order/

清算                   reckoning/ReckoningController           odts-linear-web/reckoning/
                        sblbooking/service/InterestEodService

结算                   edsBoot/controller/PBContractFileGenerate
                        action/web/contractSettle/

监管报送               sac-report/                             odyssey-report-processing-service/
                        action/sacReport/

风控                    eds-rm-web/risk-management/            odts-linear-web/riskMgt/
                        hedging-as/BaseRiskCheckControl

运营监控               eva-master/ (Python + Prometheus)       (无)

12. 如何快速定位代码

场景 1:找到某个合约的字段在哪里用

  1. 字段名里有 E 编码的 → 搜索 _eXXXXXX。如 _e020001 在 NeedsPricingPBtrs 中使用
  2. 字段名没有编码的 → 搜索字段名(如 underlyingProperty
  3. EAV 模式存储的 → 搜索 EDS_CONTRACTELEMENTVALUEEOD

场景 2:理解一个 API 端点的处理流程

  1. edsBoot/controller/ 下找到对应的 Controller
  2. 查看它调用了哪个 Service(在 edsBoot/service/ 下)
  3. Service 通常会调用 MyBatis Mapper(在 edsBoot/mapper/ 下)
  4. Mapper 的 SQL 在 edsBoot/resource/mapper/ 下的 XML 文件中

场景 3:区分一代和二代的代码

  • com.cicc.action.* → Struts2(一代,逐渐淘汰)
  • com.cicc.edsBoot.* → Spring Boot(一代后期,当前主力)
  • ~/odyssey/* → 二代微服务(新开发)

场景 4:找到产品的定价逻辑

  1. 从合约的 product_e000027 确定产品类型(“2”/“4”/“5”)
  2. eds-price-server/ 下找 PricingEngine 中对应的 switch case
  3. 对应的 StructuredProduct 子类实现具体的定价模型

13. 一些你需要知道的缩写

缩写全称含义
EDSEquity Derivatives System股权衍生品系统
SBLSecurities Borrowing and Lending证券借贷
PBPrime Brokerage主经纪商
TRSTotal Return Swap总收益互换
RHEGRange Hedge区间保本
ACAAutomatic Callable自动赎回结构(雪球)
MTCMark-to-Call / Margin to Cover追保
NPPNet Present Principal净名义本金
BPSBasis Points基点 (1bp = 0.01%)
EODEnd of Day日终批处理
SACSecurities Association of China中国证券业协会
CSDCChina Securities Depository and Clearing中登公司
ACPApplication Communication Protocol应用通信协议
OMSOrder Management System订单管理系统
PKS项目专用缩写(可能是外包或通道)

14. 为什么这份地图存在——没有它的业务代价

新人在代码海洋中迷路的 3 个月

新人 A(2023 年入职):
  第 1 周:配环境(ODTS 1 项目 4 个子模块,每个有不同构建方式)
  第 2 周:PR 来了——"修改某 ISDA 合同的结算日期逻辑"
    新人花了 3 天找到代码在哪——EdsSubContractDBModel 的 80+ 字段
    因为不知道"结算日期"在数据库里叫 settleDate 还是 settlementDate 还是 payDate
    最后发现有 3 个不同的日期字段在 3 个不同的地方被设置
  第 3 周:另一个 PR——"修复保证金计算 bug"
    这次他找到了代码——但改了 trade 模块的保证金计算,影响了 eod 模块的调用
    测试没覆盖到,UAT 才发现
  第 4-12 周:逐渐摸索出代码结构
    前 3 个月平均每个 PR 要 2-3 天(其中 50% 时间花在找代码位置)

业务成本:
  → 3 个月的非生产力期 × 月薪 = 约 15 万人民币的隐性成本
  → 期间出的 bug(修改错模块)需要 senior 花时间 review 和回滚
  → Senior 的 review 时间被稀释——原本可以花在架构改进上的时间

生产事故中浪费的定位时间

2022 年生产事故:
  → 某个场外期权的估值在某个条件下显示为 0
  → 值班开发花了 2 小时才找到原因——代码在 GPricingEngine 的
    一个深层路径里,被 5 层 if-else 包裹
  → 但实际上这个 bug 在 6 个月前就被引入了一块代码
    "看起来和估值无关"的 refactoring 改了一个 return 值
  → 修复只花了 10 分钟——找到代码花了 2 小时

经济损失:
  2 小时 × 值班团队(1 开发 + 1 运维 + 1 业务验证)
  如果是在交易时段,估值显示问题可能导致错误的风险暴露判断
  虽然这次没有直接资金损失,但时间成本是真实的

”看起来对”的模块——改错地方的代价

案例(2021 年):
  需求:"修改合约终止日期的显示格式"
  开发找到了"显示日期"的代码——在一个前端格式化工具类里
  改了 3 行代码,测试通过,部署上线
  一个月后运营发现某个报表的终止日期是全 0
  → 因为那个工具类被 12 个不同地方调用
  → 开发只测试了"自己知道的那 3 个调用方"
  → 另外 9 个没测的调用方直接崩了

影响:
  → 报表修复花了 1 周
  → 运营对该时间段内的报表数据信任度下降
  → 最终追查发现:这个需求应该改的是后端日期计算逻辑,而不是前端格式化

没有代码地图时,"看起来对的修改"往往是"偶发正确"。
有了地图,才能判断"这段代码在哪里"和"谁在用这段代码"。

Senior 开发的单点依赖

这套系统在 10 年里有超过 20 人的开发人员进出。代码地图解决的不仅是技术问题——它解决的是人员流动的风险

现实:
  → 2020 年 eds-web-app 的原始架构师离职
  → 他脑子里有一张完整的代码地图:"xx 功能在 xx 包下的 xx 文件"
  → 这张地图没有文档化
  → 他走后,后续团队花了大约 6 个月才重建同等程度的代码认知
  → 这 6 个月里,任何涉及跨模块的修改都充满了不确定性

这就是 ODTS-33 存在的理由——不让"代码知识"随人走。

15. 代码阅读路线图(推荐顺序)

如果你刚进入这个系统,按这个顺序读代码:

第一天:读模型

  1. EdsSubContractDBModel.java → 理解 80+ 个字段和编码体系
  2. EdsSubRequestDBModel.java → 理解事件机制
  3. ProductType.java → 理解产品分类

第二天:读定价 4. PricingEngine 的 switch-case → 理解 30+ 产品结构类型 5. GPricingEngine → 理解 Greeks 计算

第三天:读交易流程 6. edsBoot/controller/ → 理解 API 入口 7. edsBoot/service/ → 理解业务逻辑 8. InterestEodService → 理解 EOD 流程

第四天:读前端 9. odts-linear-web 的 27 个模块 → 理解产品功能全貌 10. eds-rm-web → 理解风控

第五天:读周边系统 11. hedging-as → 理解对冲和状态机 12. sac-report → 理解监管报送 13. eva-master → 理解运营监控