Sftp File Exchange
· · ·
题目进度 0 / 0 ✓ 0
ODTS-59: SFTP 文件交换——与银行和托管行的数据桥梁
目标读者:想理解 ODTS 如何通过文件与外部机构(结算行、托管行、清算所)交换数据的 BA/PM
相关文档:ODTS-14 (结算), ODTS-43 (通信架构), ODTS-52 (外部系统可视化)
为什么 BA/PM 需要理解文件交换
场外衍生品交易中,银行和托管行代表了”最后一个信任环节”——它们持有交易台的真实资金。如果文件交换出了问题,资金不会自动移动到正确的位置。这在 2022 年之前是最常见的故障模式之一。
文件交换失败的真实代价:
- 对账单延迟: 交易台每天需要银行对账单来确认当天所有资金变动。如果对账单文件在 09:00 前未到达,风控无法开盘前确认资金头寸。某交易台曾遇到对账单延迟到 11:00,风控在那 2 小时内只能凭系统估计头寸做决策——差一点把隔夜透支 (overdraft) 当成了可用资金,多做了 2000 万的资金划出。
- 结算指令遗漏: EOD 批处理生成的结算指令文件如果因磁盘满或其他原因未上传到托管行,第二天银行不会处理那些转账。运营发现时已经是次日下午。补救措施:紧急发传真、电话确认、手工入账。每次此类事故平均消耗运营团队 4-6 小时处理善后,每年约 3-5 次 = 12-30 小时/年。
- 格式变更断联: 银行修改文件格式而不提前通知(真实发生过),解析器崩溃,所有当日对账单无法自动处理。运营需要人工下载、解读、核对每一笔——对于日均 50 笔以上转账的交易台,这意味着 1-2 个 FTE 整天无法做其他工作。 这种”银行改格式”事件,每家交易台平均每 1-2 年经历一次。
- 文件重传导致重复入账: 运营不确定对账单文件是否已送达,重传一次,银行收到两个相同文件。部分银行的处理系统不是幂等的——两笔相同转账都被执行。追回多付的资金需要 2-4 周。
概述
尽管 ODTS 在内部服务间使用 Protobuf TCP、Kafka、REST 等多种现代协议,但与外部金融机构的通信仍然大量依赖 SFTP 文件交换。这是金融行业的现实——银行和托管行的系统通常只支持文件级接口,不支持 API。
SFTP 文件交换用于:
- 发送结算指令给托管行
- 接收银行对账单
- 发送质押品指令给清算所
- 交换客户持仓报告
架构
ODTS eds-web-app
│
│ 生成 CSV/XML 文件
▼
共享文件服务器 (内部)
│
│ SFTP 上传
▼
外部机构 SFTP 服务器 (银行/托管行/清算所)
│
│ SFTP 下载
▼
外部机构处理结果
│
│ SFTP 上传
▼
ODTS 文件服务器 (拉取结果文件)
│
│ 解析结果文件
▼
更新数据库状态
文件格式
结算指令文件 (CSV)
发送给托管行的结算指令,每行一条转账:
# 结算指令文件 — 生成时间:20250716-183000
# 格式: 流水号,交易台账号,对手方账号,对手方名称,金额,币种,摘要
CT20250716001,3100XXXXXXXX,6200XXXXXXXX,某某投资有限公司,1230456.78,CNY,期权权利金-SNOWBALL202507001
CT20250716002,3100XXXXXXXX,6200XXXXXXXX,ABC Asset Management,500000.00,CNY,追保-MARGIN202507001
CT20250716003,3100XXXXXXXX,6200XXXXXXXX,PingAn Insurance,2000000.00,CNY,分红-SWAP202507008
对账单文件 (CSV)
银行返回的对账单:
# 对账单 — 银行: ICBC, 日期:20250716, 账号:3100XXXXXXXX
# 日期,摘要,支出,收入,余额,对方账号,对方名称
20250716,转账支出,1230456.78,,87654321.00,6200XXXXXXXX,某某投资有限公司
20250716,转账收入,,500000.00,88154321.00,XXXXXXXXXXX,ABC Capital
XML 格式的机构指令
某些托管行要求 XML 格式:
<SettlementInstruction>
<Header>
<Sender>CICC</Sender>
<Receiver>HSBC_CUSTODY</Receiver>
<GenerationTime>2025-07-16T18:30:00+08:00</GenerationTime>
<BatchId>BATCH20250716001</BatchId>
</Header>
<Instructions>
<Instruction>
<Ref>CT20250716001</Ref>
<DebitAccount>3100XXXXXXXX</DebitAccount>
<CreditAccount>6200XXXXXXXX</CreditAccount>
<Amount Currency="CNY">1230456.78</Amount>
<ValueDate>2025-07-17</ValueDate>
<Purpose>期权权利金结算</Purpose>
</Instruction>
</Instructions>
</SettlementInstruction>
文件处理管道
EDS EOD 批处理 (第 8 步: 生成外部文件)
│
│ 生成结算指令 CSV → 共享目录 /data/outbound/settlement/
│ 生成持仓报告 XML → 共享目录 /data/outbound/report/
│ 生成质押品指令 → 共享目录 /data/outbound/collateral/
▼
SFTP 上传脚本 (cron 定时执行)
│
│ scp /data/outbound/settlement/*.csv custodian@sfpt.custodian.com:/incoming/
│ scp /data/outbound/report/*.xml hktr@sftp.hktr.com:/upload/
▼
外部机构处理
│
│ (数小时到 T+1 不等)
▼
SFTP 下载脚本 (cron 定时执行)
│
│ scp custodian@sfpt.custodian.com:/outgoing/statement_*.csv /data/inbound/statements/
│ scp hktr@sftp.hktr.com:/download/ack_*.xml /data/inbound/ack/
▼
文件解析
│
│ SettlementStatementParser → 更新 CashTransfer 状态
│ HKTR_AckParser → 更新监管报送状态
▼
数据库更新
文件命名规范
| 文件类型 | 命名规则 | 示例 |
|---|---|---|
| 结算指令 | SETTLE_{batchId}_{date}.csv | SETTLE_B20250716_20250716.csv |
| 银行对账单 | STM_{bankCode}_{account}_{date}.csv | STM_ICBC_3100XXXX_20250716.csv |
| 持仓报告 | POS_RPT_{date}_{type}.xml | POS_RPT_20250716_HK.xml |
| 质押品指令 | COLL_{type}_{date}.csv | COLL_CALL_20250716.csv |
常见问题
1. 文件延迟
外部机构处理文件需要时间(数小时到 T+1)。ODTS 使用固定间隔轮询(每 30 分钟检查一次结果文件目录)。如果重要批次超时未返回结果,运营需电话联系银行。结算指令文件延迟到 16:00 后才被银行处理,意味着当天资金无法到账,客户需要多等一个交易日。如果这笔资金是用于满足 margin call 的,交易台暴露在额外风险敞口下多一个交易日。
2. 文件格式变更
银行可能在不通知的情况下修改文件格式(新增列、修改日期格式)。此时解析器会失败,运营需手动处理并通知开发团队更新 SettlementStatementParser。
3. 重复文件
SFTP 不提供去重保证。ODTS 通过文件名中的 batchId 做幂等检查——同一个 batchId 的文件不会被处理两次。
关键代码目录
eds-web-app/src/.../fileexchange/
├── sftp/
│ ├── SftpConfig.java ← SFTP 连接配置
│ ├── SftpUploader.java ← 文件上传封装
│ └── SftpDownloader.java ← 文件下载封装
├── parser/
│ ├── SettlementStatementParser.java ← 对账单 CSV 解析
│ ├── CustodyInstructionParser.java ← 托管行指令 XML 解析
│ └── HKTR_AckParser.java ← HKTR 回执解析
├── generator/
│ ├── SettlementFileGenerator.java ← 结算指令文件生成
│ ├── PositionReportGenerator.java ← 持仓报告生成
│ └── CollateralInstructionGenerator.java ← 质押品指令生成
└── batch/
└── ExternalFileBatchJob.java ← EOD 批处理中的文件生成步骤