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

Cats Comparison

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

50. CATS —— 商品部的”迷你ODTS” / The Commodity Desk’s “Mini ODTS”

缘起:找到CATS

CATS(Commodity Auto Trading System)位于 /odts1/CATS 目录中。从目录名看它和 ODTS 在同一级,但从深处看它是商品部自用的交易系统。Git log 显示只有 79 次提交,活跃期约一年(2019-2020),之后再无人问津。

CATS 并非一个独立开发的系统——从它的代码结构看,它是从 ODTS/EDS 的体系”长出来”的。包名 com.cicc.commodity、共享的 webside-security、统一的 Ant 构建框架,都与主 OTC 系统出自同一套基础设施。这像是一个商品部团队拿主系统的脚手架,为 LME 金属期货业务搭了一套专用的交易系统,然后又把 OTC 衍生品 支持加了进去。

CATS 的两张面孔 / Two Faces

CATS 最核心的特征是:一个 WAR 里装了两个业务域。

Face 1:交易所商品(Exchange-Traded Commodities)

这是 CATS 的原生业务——处理港交所/ LME 等交易所的金属期货和期权交易。核心表 T_COMMODITY 包含:

字段含义等价 ODTS 概念
EXCHANGE交易所代码(LME/SHFE/etc.)无(ODTS不接交易所)
EXCHANGE_SYMBOL交易所品种代码
TICKER行情代码UnderlyTicker
CONTRACT_NAME合约名称
CONTRACT_SIZE每手数量
CONTRACT_NUMBER合约手数Quantity
POSITIONLong/ShortSide
TRADE_STATUSOpen/Close/PendingTradeStatus
CLEARING_FEE / EXCHANGE_FEE / STAMP_DUTY / TRANS_LEVY / COMMISSION_FEE费用明细无统一字段
FEED_REF / FEED_STATUS数据源回执类似但不尽相同
SETTLE_AMOUNT / SETTLE_DATE结算金额和日期Settlement

这本质上是 期货交易管理系统,业务范围包括:

  • 记录交易所成交(从经纪人/ Bloomberg 导入)
  • 计算持仓和盈亏(每日盯市 P&L)
  • 管理保证金(Initial Margin、Broker Margin Balance)
  • 生成结算单和对账单(Statement / StatementMonthly)
  • 费用管理(佣金、交易所费、印花税、过户费等)

Face 2:OTC 衍生品(Commodity OTC Derivatives)

这是后来加入的——CATS 在商品期货之上 + 了 OTC 支持,用另一张核心表 T_OTC_TRADE 存储。从字段数量看(约 80+ 列),这是一张典型的 单表大宽表——与 ODTS 早期做法完全一致。

CATS 支持的 OTC 产品线

ContractType.java 中看到的品类:

代码品类中文名ODTS 是否有等价品
VANVanilla Option香草期权
VANSVanilla Spread香草价差无(ODTS 用 Barrier 实现近似效果)
CPSCall Put Spread看涨看跌价差
SFSharkFin鲨鱼鳍无(最接近的是 Barrier)
DSFDouble SharkFin双鲨鱼鳍
ESFEuropean SharkFin欧式鲨鱼鳍
EDSFEuropean Double SharkFin欧式双鲨鱼鳍
OTOne Touch触碰期权
FXFX外汇有(但 CATS 只做商品端的 FX)
ForwardForward远期
FutureFuture期货无(ODTS 不做交易所期货)
OptionOption期权

SharkFin(鲨鱼鳍) 是 CATS 最有特色的产品。它是一种保本型结构化产品,设有一个上限价格(knock-out level),标的在期限内如果未触碰上限则到期获得固定收益,触碰后收益按标的涨幅线性计算但封顶。与 ODTS 的 Snowball 相比:

  • SharkFin:保本、单层 barrier、期限较短(通常 1-3 个月)
  • Snowball:不保本、两层 barrier(敲入/敲出)、期限长(12-24 个月)、票息递延

CATS 的 T_OTC_TRADE 包含了面向这些结构所需的字段:

BARRIER_PRICE, BARRIER_SIZE,      -- 障碍价格/比例
HIGH_KNOCK_OUT_PRICE,              -- 敲出价格(SharkFin 上限)
LOW_KNOCK_OUT_PRICE,               -- 敲入价格
OBSERVATION_DATE_BEGIN,            -- 观察期开始
MIN_RETURN,                        -- 最低回报率
DIGITAL_SIZE,                      -- 数字期权固定回报
KICKOUT_RETURN,                    -- 敲出回报率
NOTIONAL_AMOUNT                    -- 名义本金

OTC 业务的辅助模块

CATS 为 OTC 业务补充了完整的交易后模块:

模块CATS 实现ODTS 对比
P&L按产品类型拆分:OTC_PNL_AU/OTC_PNL_FUTURE/OTC_PNL_OPTION/OTC_PNL_VANILLA + 汇总 OTC_SUMMARY + 历史 OTC_HIS_SUMMARY统一 P&L 表 + Delta/Gamma/Vega 风险表
定价PricingCalculator.java 用 Black-76 + OTC_UNDERLY(含 sigma/价格/利率)Black-76 + Monte Carlo + Python bridge
合约确认函JasperReports PDF 生成(中英双语)同上 + Murex/ Bloomberg XML
估值OTC_VALUE_ITEM 逐日盯市ValuationDay 批量估值
资金管理CASH_MANAGEMENT + CASH_VOUCHER(凭证)CashMovement
抵押品COLLATERALCollateral(更复杂)
报告OTC_REPORT + OTC_REPORT_TEMPLATEReporting engine
平仓OTC_CLOSED_TRADE + OTC_PARTIAL_SETTLED_TRADE类似
Termsheet自动生成 PDF类似

技术栈对比 / Tech Stack Comparison

层面CATSODTS
Web 框架Struts 2.3JFinal (世界1) / Spring Boot (世界2)
ORMHibernate 3.6.7 + XML mappingActiveRecord (世界1) / MyBatis (世界2)
SpringSpring 3.0.6Spring Boot 2.x
前端FreeMarker 服务器端渲染 + jQuery jqGridVue SPA (世界1) / Vue3 (世界2)
数据库Oracle(C3P0 连接池)MySQL
构建Ant + WebLogic 部署Maven + Jenkins
消息ActiveMQ 5.3RabbitMQ
认证CAS SSO + Spring Security类似(同一 CAS 体系)
报表JasperReports 6.3JasperReports + 定制
数据集成Bloomberg 数据接入Bloomberg + Wind + 自采
缓存Ehcache + OSCacheRedis
单元测试无(测试目录为空)JUnit + Mockito

架构风格差异

CATS 是典型的 单层单体应用——一个 WAR 部署到 WebLogic,一个 commodity.hbm.xml 包含全部 65 个实体映射,所有 Action 继承同一个 BaseAction。代码量虽然不大(79 commits),但 65 张表说明它是一个表驱动的系统——每个业务概念都有对应的数据库表,CRUD 骨架从 ODTS 体系中复制后定制。

ODTS 经历了从单体到微服务的完整演化路径(详见 04-Modernization),40+ 个内部项目 + 8+ 个外部集成系统,Maven 多模块构建,REST API 网关。

数据模型对比

CATS 的 T_OTC_TRADE 是一个典型的 大宽表反模式——无论 Vanilla、SharkFin、FX 还是 One-Touch,全部塞进同一张表。这种做法:

  1. 和 ODTS 早期做法一样——ODTS 的 t_trade_order 也曾是这种”一把梭”的通用结构
  2. 问题也一样——字段可空(nullable)是常态,约束只能靠代码,DB 本身无法保证数据完整性
  3. 但 CATS 规模小,问题不致命——79 次提交的代码量,一个开发者就能维护

CATS 比 ODTS 多了一个处理维度:交易所。 它的 T_COMMODITYEXCHANGEEXCHANGE_SYMBOLFEED_REF 等字段,这是 ODTS 完全不需要的——ODTS 只做场外。

要命的业务逻辑 / Business Logic Worth Dying For

费用计算

交易所期货的费用极其复杂。CATS 的 Commodity 模型中有 7 个费用字段:

  • CLEARING_FEE(清算费)
  • EXCHANGE_FEE(交易所费)
  • STAMP_DUTY(印花税)
  • TRANS_LEVY(交易征费)
  • COMMISSION_FEE(佣金)
  • OTHER_FEE(其他费用)
  • MARKUP_FEE(加价)

相比之下,ODTS 没有这些细分——OTC 衍生品没有交易所费/印花税的概念,费用结构简单得多(一般就是名义本金 × 费率)。

保证金模型

CATS 的保证金系统比 ODTS 复杂,因为它有两种保证金:

  1. 交易所保证金——交易所规定的 Initial Margin,通过 BROKER_MARGIN_BALANCEINITIAL_MARGIN_PER_LOT 管理
  2. 客户保证金——MARGINMARGIN_CALL 表管理,CLIENT_MARGIN_MONITOR 监控
  3. LME 特有——LME 是 tier 保证金制度,LME_TIER_MARGIN_TABLELME_TIER 为此而生

ODTS 的保证金(详见 16-Margin-Calls)主要是 IM + VM,通过 ISDA CSA 协议约束,不需要关心交易所的 tier 保证金计算。

为什么说 CATS 是”迷你 ODTS”?

从代码树结构看,CATS 和 ODTS 的关系是:

/odts1/
├── CATS/                  ← 商品部自用
│   └── commodity/         ← 单一项目
├── eds-web-app/           ← OTC 衍生品(世界1, 2016-2018)
├── option-frontend/       ← OTC 前端
├── finance-data-backend/  ← OTC 数据(世界2)
├── trade-backend/         ← OTC 交易(世界2)
├── sentinel-backend/      ← OTC 风控
├── lens-backend/          ← OTC 报表
├── ...

CATS 是一个 小号、单机的 ODTS——它用 ODTS 的框架和设计模式,但只服务商品部这一个业务线。它的 OTC 部分几乎是对 ODTS 的简化模仿:

维度ODTSCATS
开发团队10+ 人持续 10+ 年2-3 人迭代约 1 年
代码规模100K+ commits, 45+ 项目79 commits, 1 项目
产品复杂度Snowball、TRS、NDF、多标的 BasketSharkFin、Vanilla、CPS
交易量级千亿级名义本金商品部级别(小几个数量级)
定价模型Black-76 + Monte Carlo + PythonBlack-76(纯 Java)
对接系统恒生、地杰、Murex、BloombergBloomberg(主要是行情)
监管报告SAC/ SFC/ ISDA/ NAFMII 全面覆盖基本无(交易所已有清算所报告)

业务代价:一个被放弃的”迷你系统”的真实成本

79 次提交,1 年后无人维护

CATS 在 2019-2020 年开发了约一年,79 次提交后彻底停更。

投入(估算):
  → 2-3 名开发,约 1 年
  → 人力成本:约 150-200 万人民币
  → 产出:1 个 WAR 包,65 张表,覆盖 LME 期货 + 商品 OTC

为什么停了?
  → 商品部的 OTC 业务量始终不大("小几个数量级")
  → 维护成本 vs 业务价值不匹配
  → 2020 年后商品部可能把 OTC 业务迁回了主 ODTS 或交给了别的团队
  → 但 CATS 的代码和数据库并没有删除——它"死"在那里

PM/BA 注意:
  当你看到一个内部系统"停更"但没被回收时,
  它变成一个"技术债定时炸弹"——
  某天有人需要查 2019 年的一笔商品 OTC 交易,
  发现数据只在 CATS 的 Oracle 库里,
  而 CATS 的部署环境可能已经无法启动。

同一客户的”两边账”——CATS vs ODTS

CATS 做商品 OTC,ODTS 做金融 OTC。如果同一个机构客户既做商品又做金融衍生品:

场景:
  → 客户 A 在 CATS 里有一笔 SharkFin(商品 OTC)
  → 客户 A 在 ODTS 里有一笔 Snowball(金融 OTC)
  → 客户 A 的总信用风险需要合并计算(这是监管要求的)

问题:
  → CATS 的信用风险表和 ODTS 的完全独立
  → 没有自动的"跨系统客户合并"机制
  → 风控团队要手工把两个系统的客户敞口汇总
  → 手工汇总 → 出错概率高 → 客户总敞口可能被低估

业务影响:
  → 2019-2020 年商品 OTC 量小,这个问题不突出
  → 但如果有大客户跨两个系统,手工合并就是隐患
  → 这正是为什么"系统复制"在合规视角下是危险的:
    每个副本都维护一份客户数据,合并时可能漏算

测试目录为空——生产环境的隐性风险

CATS 的技术栈对比中明确写着:单元测试:无(测试目录为空)

这意味着:
  → 任何一个 bug 修复都没有自动化验证
  → 改一个费用计算逻辑,只能靠"上线后看对不对"
  → 如果有客户因为费用算错而投诉,那是事后才发现

对比 ODTS:
  → ODTS 有 JUnit + Mockito(虽然覆盖率也有限,见 46-Testing-and-QA)
  → CATS 连这个都没有

对于 BA/PM:
  一个没有测试的系统如果被用于生产(哪怕是小业务),
  每一次代码改动都是"盲飞"。
  商品 OTC 虽然量小,但一笔错误的 SharkFin 敲出计算,
  仍可能导致对客户的多付或少收。
  1. 同一个公司内部的”系统复制”是常态——CATS 证明了当一个部门有垂直业务需求时,他们会拿现成的框架搭一套定制系统。这对分析师意味着:CICC 内部可能还有更多类似的”派生系统”。

  2. 商品期货 ≠ OTC 衍生品——CATS 同时做这两个,但它们是根本不同的业务:

    • 期货:标准化合约、交易所清算、逐日盯市、费用复杂
    • OTC:非标准化合约、双边清算、ISDA 约束、费用简单但条款复杂
    • 放在同一系统中是”历史包袱”,并非设计上的优势
  3. SharkFin vs Snowball 的对比值得深究——二者都是结构化产品,但结构完全不同。CATS 做 SharkFin 说明 CICC 的商品部客户群体偏好 低风险保本型 产品,而 ODTS 的 Snowball 客户(机构投资者)愿意承担更大的风险以换取更高收益。

  4. 技术选择反映团队规模——CATS 用 Ant + Struts2 + FreeMarker + Oracle,全是”重”基础设施的选择,适合小团队用成熟框架快速交付。ODTS 在规模扩大后转向 Spring Boot + Maven + Vue,是”现代化”的自然演进。