搬迁(算法体逐字未动,仅换命名空间与归属): - SwapInterest.Round/AccrualDays/FundingLegPrecision + AccrualBoundary/InterestResult → YLErpDAL/Modules/SwapModule/Accrual/InterestMath.cs - AccrualTrace → Accrual/AccrualTrace.cs(被迫同迁:其 MarkStart 引用 AccrualBoundary, Core 不能反向依赖 DAL) - 引用切换:Simple/CompoundInterestAccrual、AccrualPolicy、SwapCalcTrace、SwapDealService (保留 using YLErp.Derivatives.Interest——IIndexFixer/IndexFixerBase 留 Core) 删除(零生产引用,孤儿清零): - Core:SwapInterest.cs 算法方法(AccrueSimple/AccrueCompoundInArrears/ApplyUnwind/ AccrueUnrealized/ToInterestRate,未接线且与 DAL 生产实现舍入/rollover 口径已分叉)、 AccrualContext.cs、InterestRate.cs - DAL:AccrualState.cs(零引用死类) - 测试:SwapInterest_CompoundInArrears_RolloverTimingTests.cs(仅测已删原语) 验证:两解决方案 Rebuild 0 错误;磁盘 SwapInterest. 残留 0;影子/分红/场景 86/86 通过 (含 Accrual 3 影子对账、Margin 影子、divPower 新增 AutoUnwindMultiPartial)。 注:AccrualContext 默认精度 11 与生产 12 的分叉隐患随删除一并消除; 已删原语若将来重建须先补对账测试,勿凭记忆复原(ARCHITECTURE.md 已留警告)。
147 lines
6.7 KiB
Markdown
147 lines
6.7 KiB
Markdown
# SwapModule 架构说明
|
||
|
||
> 本文档描述 2026-08 重构后的模块结构。所有改动均通过编译 + 全量测试验证(零回归)。
|
||
|
||
## 三大限界上下文
|
||
|
||
TRS 的三类业务各自独立,通过 SwapInterest 纯函数库共享计息能力:
|
||
|
||
```
|
||
SwapInterest (Core 纯函数)
|
||
"本金 × 利率 × 天数 / 年化"
|
||
不依附于任何腿
|
||
↑
|
||
┌──────────────┼──────────────┐
|
||
│ 谁需要算利息就调它 │
|
||
│ │
|
||
┌─────┴──────┐ ┌──────┴───────┐
|
||
│ FundingLeg │ │ Margin │
|
||
│ 融资腿 │ │ 保证金 │
|
||
│ │ │ │
|
||
│ 客户付券商 │ │ 客户交的抵押品│
|
||
│ 的融资成本 │ │ │
|
||
│ spread+FR007│ │ 余额/追保/返还│
|
||
│ mode 1/2/9 │ │ mode 5/6 │
|
||
└─────────────┘ └──────────────┘
|
||
|
||
┌─────────────┐
|
||
│ ReturnLeg │
|
||
│ 标的端 │
|
||
│ │
|
||
│ 标的总回报 │
|
||
│ 价格+分红 │
|
||
└─────────────┘
|
||
```
|
||
|
||
**命名规则(防歧义)**:
|
||
- `Funding` = 融资成本(不用 Interest,避免和通用"利息"混)
|
||
- `Return` = 标的总回报(不用 Float,避免和 FR007 浮动利率混)
|
||
- `Margin` = 保证金(客户交的抵押品,有余额和返息,不走融资腿的计息基数框架)
|
||
- `FloatRate` = FR007 浮动利率(唯一含义)
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
SwapModule/
|
||
├── FundingLegs/ 融资腿(mode 1/2/9)
|
||
│ ├── IFundingLegStrategy 策略接口 + NotionalResult 值对象
|
||
│ ├── FixedAmountLeg mode 1 固定值(恒=Fix 不随比例变)
|
||
│ ├── ContractNotionalLeg mode 2 合约名义本金规模
|
||
│ ├── UnderlyingEntryFullPriceLeg mode 9 标的期初全价
|
||
│ └── FundingLegStrategyFactory 按 mode 分发
|
||
│
|
||
├── Margin/ 保证金(mode 5/6)
|
||
│ ├── MarginModes mode 判断(含 ForLinq for EF Core)
|
||
│ └── MarginCalc 纯函数(PreviousBalance/FlipDirection/AccumulateSettlement)
|
||
│
|
||
├── ReturnLegs/ 标的端
|
||
│ ├── ReturnLegSummary 标的端汇总值
|
||
│ ├── QtyRollforward 数量递推(预留 corpActionDeltaQty 给公司行为)
|
||
│ ├── MtmCalc 盯市(MarketValue + UnrealizedPnl)
|
||
│ ├── DividendCalc 增值税后票息(AfterTax + AfterTaxRaw)
|
||
│ ├── DirectionRatio 方向因子(LongShort + ReceivePay)
|
||
│ └── PositionValueCalc 持仓价值汇总(利息端 + 浮动端)
|
||
│
|
||
├── Accrual/ 计息(生产实现,自洽域)
|
||
│ ├── InterestMath 共用数学:Round/AccrualDays/FundingLegPrecision + AccrualBoundary/InterestResult
|
||
│ ├── SimpleInterestAccrual 单利纯函数(AccrueEod 单日 + AccruePeriod 多日)
|
||
│ ├── CompoundInterestAccrual 复利纯函数(EodBasis/AccrueEod/AccruePeriod)
|
||
│ ├── AccrualPolicy 计息政策(算头算尾/单复利/重置周期/年化)
|
||
│ ├── AccrualTrace 计息 trace 收集器(SwapCalcTrace.Write 常驻落盘)
|
||
│ └── FundingLegRate all-in 利率值对象
|
||
│
|
||
├── SwapDealService.cs 盘中平仓/互换主逻辑
|
||
├── SwapEodPositionService.cs EOD 日终归档主逻辑
|
||
├── SwapDealIndexFixer.cs SwapDealService 专用取价器(委托 TryGetFloatRate)
|
||
└── Fr007IndexFixer.cs FR007 取价生产实现
|
||
```
|
||
|
||
## Core 层(Framework/YLErp.Core/Interest/)
|
||
|
||
```
|
||
Interest/
|
||
├── IIndexFixer.cs 取价接口
|
||
└── IndexFixerBase.cs 取价日计算工具
|
||
```
|
||
|
||
> 注:① `Fr007IndexFixer.cs`(FR007 取价生产实现)在 SwapModule 下,不在本目录。
|
||
> ② 2026-08 计息类型(InterestMath/AccrualBoundary/InterestResult/AccrualTrace)已整体迁至 SwapModule/Accrual/,
|
||
> Core 不再持有计息实现。原 Core 层 SwapInterest 的算法方法(AccrueSimple/AccrueCompoundInArrears/ApplyUnwind/
|
||
> AccrueUnrealized/ToInterestRate)与 AccrualContext/InterestRate 从未接线(生产走 Accrual/ 目录),作为孤儿死代码删除——
|
||
> 其舍入/rollover 口径与生产实现已分叉,若将来重建须先补对账测试,勿凭记忆复原。
|
||
|
||
## InterestModeEnum(显式赋值,DB 契约)
|
||
|
||
```
|
||
Unknown = 0
|
||
固定值 = 1 → FundingLeg
|
||
合约名义本金规模 = 2 → FundingLeg
|
||
初始预付金 = 5 → Margin
|
||
追加预付金 = 6 → Margin
|
||
标的期初全价 = 9 → FundingLeg
|
||
|
||
已删除(无历史数据):
|
||
3 = 持仓名义本金(死代码)
|
||
4 = 持仓市值(死代码)
|
||
7 = 多头存续名义本金(界面已禁用)
|
||
8 = 空头存续名义本金(界面已禁用)
|
||
```
|
||
|
||
## 已消除的 inline 重复
|
||
|
||
| 公式 | 原重复 | 收敛到 |
|
||
|---|---|---|
|
||
| FR007 取价 | 6处 | IIndexFixer |
|
||
| 保证金 mode 判断 | 10处 | MarginModes |
|
||
| UnderlyingMarketValue | 4处 | MtmCalc.MarketValue |
|
||
| PosiMtmPnL | 4处 | MtmCalc.UnrealizedPnl |
|
||
| PosiQuantity 递推 | 2行 | QtyRollforward.Calc |
|
||
| 增值税公式 | 5处 | DividendCalc |
|
||
| 方向因子三元式 | 7处 | DirectionRatio |
|
||
| SwapPositionValue | 8处 | PositionValueCalc |
|
||
| CalcNotionalByMode | 整个方法 | 已删除(融资腿走工厂,保证金内联) |
|
||
|
||
## 方向因子类型规范
|
||
|
||
所有方向因子(多空 +1/-1、收付 +1/-1)统一用 **int**,不用 decimal:
|
||
|
||
| 纯函数 | 参数 | 类型 |
|
||
|---|---|---|
|
||
| MtmCalc.MarketValue | shortRatio | int |
|
||
| MtmCalc.UnrealizedPnl | shortRatio, ratio | int |
|
||
| DirectionRatio.LongShort | 返回值 | int |
|
||
| DirectionRatio.ReceivePay | 返回值 | int |
|
||
| MarginCalc.FlipDirection | 返回值 | int |
|
||
| PositionValueCalc.Calc | ratio | int |
|
||
|
||
## 待后续改造
|
||
|
||
| 项目 | 依赖 | 接缝已预留 |
|
||
|---|---|---|
|
||
| 公司行为(送股/拆股) | QtyRollforward.corpActionDeltaQty | ✅ |
|
||
| 公司行为(登记日快照) | DividendCalc + BondPayment | 见 corp-action-refactor-proposal.md |
|
||
| 保证金配置/规则/占用 | MarginCalc | ✅ |
|
||
| RecordMarginCashFlow 迁入 Margin | AddClientCash 加 virtual | 待做 |
|
||
| EOD 编排拆分 | SwapPositionCompose | 待业务需求驱动 |
|
||
```
|