Commit Graph
1534 Commits
Author SHA1 Message Date
hjhan aeb55a01ad refactor(eod): 提取InterestIncomeCalc.DailyAccrual/RollRealized + MtmCalc.ReturnLegProfitSum
候选B: 3处日利息 principal*(rate+float)/annualDays → InterestIncomeCalc.DailyAccrual
候选D: 4处 PosiProfitSum=Mtm+Div+Fee → MtmCalc.ReturnLegProfitSum
候选E: 4对 RealizedInterest/RealizedInterestFee 滚存 → InterestIncomeCalc.RollRealized

SwapModule零回归(7基线/510通过)
2026-08-12 14:50:24 +08:00
张名锐 2035e1df4c fix(swap): 修复EOD平仓后收盘时结息本金计算错误
- 修正SwapDealService.GetInterests方法中平仓后结息本金语义错位问题
- 区分EOD平仓后收盘与盘中平仓前本金传参的不同语义
- 针对模式2合约名义本金规模强制覆盖为实际平仓额
- 保持模式9标的期初全价在全平时的零值处理逻辑
- 添加债券份额调整公司行动支持和记录日期资格判断
- 实现EOD仓位复制和更新时的公司行动应用逻辑
2026-08-12 14:40:03 +08:00
hjhan 1aa0579fbd refactor(eod): MarginModes.FixedAmountAndMargin + DirectionRatio.RateType提取
候选F: 3处内联 new List{固定值,初始预付金,追加预付金} → MarginModes.FixedAmountAndMargin
候选I: 7处内联 收取?Buy:Sell → DirectionRatio.RateType(direction)

SwapModule零回归(7基线/510通过)
2026-08-12 14:38:04 +08:00
hjhan af94003939 refactor(eod): DirectionRatio.ReceivePay/InterestLegPnl替换21处内联三元
SwapEodPositionService中散落的收取?1:-1三元表达式和ratio+margin flip块:
- 9处InterestLegPnl块(3-5行→1行): 收取?1:-1 + if(MarginModes)ratio=-ratio
- 12处ReceivePay三元: 收取?1:-1 → DirectionRatio.ReceivePay(dir)
- 含2处反向(收取?-1:1 → -DirectionRatio.ReceivePay)

净减约30行, 消除+1/-1写反的风险
SwapModule零回归(7基线/510通过)
2026-08-12 14:33:23 +08:00
hjhan bfa230381b refactor(accrual): 提取BuildLegRate/BuildEodPolicy消除EOD wrapper构造重复
EOD CompoundEod + SimpleEod 各有一份相同的FundingLegRate构造(3行)
和AccrualPolicy构造(5行), 共16行重复。

提取为:
- BuildLegRate(position, spread, effectiveFloat): 固定腿→Fixed, 浮动腿→Floating
- BuildEodPolicy(position, annualDays, isCompound): 算头算尾+重置周期

每个EOD wrapper从10行构造代码→2行调用, 净减12行
SwapModule零回归(7基线/510通过)
2026-08-12 14:01:24 +08:00
hjhan 9d321378ac cleanup(accrual): 删除orginPv死参数(3个方法签名+所有调用点)
源码实证orginPv在5/6个CalcDaily方法中是死参数(方法体不读取):
- CalcDailyCompoundInterest: 删 decimal orginPv(3个调用点同步删)
- CalcDailyCompoundInterestByEod: 删(1个调用点+4个测试同步删)
- CalcDailySimpleInterestByEod: 删(1个调用点+2个测试同步删)

保留orginPv的方法(真实消费者):
- CalcDailySimpleInterest: 差分公式 posiPrincipal - orginPv
- GetInterests/CalcUnwindInterest/InitSwapDealInterest: 转发链

SwapModule零回归(7基线/510通过)
2026-08-12 13:58:43 +08:00
hjhan 9d8cfb5ad0 refactor(accrual): 拆分FundingLegAccrual→SimpleInterestAccrual/CompoundInterestAccrual
单利与复利语义完全不同(单利本金恒定/复利重置日并本金),
拆成两个独立静态类,各自只含自己的方法:

SimpleInterestAccrual:
- AccrueEod (原AccrueSimpleEod)
- AccruePeriod (原AccrueSimplePeriod)

CompoundInterestAccrual:
- EodBasis (原CompoundEodBasis)
- AccrueEod (原AccrueCompoundEod)
- AccruePeriod (原AccrueCompoundPeriod)

方法名去掉Simple/Compound前缀(类名已携带类型),消除冗余
SwapModule零回归(7基线/510通过)
2026-08-12 13:40:47 +08:00
hjhan 57156feec1 refactor(accrual): 提取ResolveFloatRate收口FR007定盘逻辑
EOD单日取率(CompoundEod/SimpleEod)与intraday多日取率(BuildSegmentRates)
原各有一份相同的GetFixingDate+TryGetFixing+throw逻辑(~8行/处,3处共24行)。

提取为私有 ResolveFloatRate(position, date, fallback):
- 无浮动标的返回fallback; 取到非零fixing返回fixing; 取不到抛异常
- EOD: isResetDay ? ResolveFloatRate(...) : floateRate (1行替代12行)
- BuildSegmentRates: 循环内直接调用(1行替代8行)

净减~15行, FR007定盘逻辑收口到一处
SwapModule零回归(7基线/510通过)
2026-08-12 13:37:40 +08:00
hjhan c86633479d refactor(accrual): 接线SimpleInterest/CompoundInterest内部 + 分段修复 + 去重
CalcDailySimpleInterest/CalcDailyCompoundInterest内部逐日循环→分段纯函数(签名不变):
- AccrueSimplePeriod: AccruedToday改未缩放累计(TdInterestAmount口径)
- AccrueCompoundPeriod: 新增out finalBasis供flowEvent.InterestPrincipal精确赋值
- 修复5处分段边界bug(includeStart/includeEnd/resetCarryInterest interestPeriod=1场景)
- 提取BuildSegmentRates消除SimpleInterest/CompoundInterest取率重复
- 影子测试补AccruedToday断言关闭测试盲区

SwapModule零回归(7基线/510通过)
2026-08-12 13:09:17 +08:00
hjhan 85746d7ee9 test(accrual): 新增同日双次部分平仓字符化测试 + EOD基数快照replay诊断
- SwapUnwindSameDayDoublePartialTest: 内存Stub驱动同日两次部分平仓(30%/50%),
  验证基数线性累加(0.3N+0.35N=0.65N),推翻"基数不滚动"假设;缺口仅在
  调用方是否传陈旧notional,已文档化
- GLMS20260805ClosePercentDiffDiagnoseTest: 从Resources快照反序列化离线重跑
  EOD基数诊断,去DB化;无快照Inconclusive,保留Assert.Fail作8/5 bug护栏
2026-08-12 11:28:40 +08:00
hjhan ff937f24e7 refactor(accrual): EOD去退化差分——删除baseNotional死参数
EOD路径 orginPv≡posiPrincipal(调用点line1091/1096实证),notional==baseNotional恒成立,
差分项 notional-baseNotional 恒为0,baseNotional 是死参数。

简化:
- AccrueSimpleEod: 删 notional+baseNotional 两参数,basis=priorNotional 直赋值
- AccrueCompoundEod: 删 baseNotional 参数,非重置日 basis=priorNotional
- SimpleEodBasis 整个删除(不再需要)
- CompoundEodBasis 去掉 baseNotional 参数
- EodContext trace 去掉 baseNotional
- 差分注释块删除(EOD不再有差分)

差分逻辑 notional-baseNotional 只该存在于 unwind 专用路径(Period函数本就没有baseNotional)
净减20行(18增/38删),SwapModule零回归(7基线/508通过/8跳过)
2026-08-12 10:58:53 +08:00
hjhan ffd539d8c3 refactor(accrual): 抽出CompoundEodBasis/SimpleEodBasis消除基数公式重复
- 基数差分公式(priorNotional+notional-baseNotional)原在AccrueCompoundEod内部与调用点各算一遍
- 抽成public static单一真相源: CompoundEodBasis/SimpleEodBasis, 纯函数与调用方共用
- 差分语义文档集中到一处(EOD退化为priorNotional / unwind增量生效)
- 吸收外部review: 三元拆具名方法 + 消重复, 但否决priorFloatingLegNotional(orginPv非浮动腿概念)
- 影子测试16/16绿, SwapModule零回归(7基线/508通过)
2026-08-12 10:48:04 +08:00
lisong b763192cab Merge branch 'glms/feature/1.4.2_0808' of http://git.yiliantech.com/gitlab/otc-dev/zszq-trs into glms/feature/1.4.2_0808 2026-08-12 10:47:56 +08:00
嬴政 时 f29aee753a #EQD-7024 国联民生-开平仓费用悬浮文案改为“我方收取交易费用”,仅更改文案,估值与平仓计算逻辑均不变 2026-08-12 10:46:43 +08:00
hjhan 3b02440979 refactor(accrual): 接线CalcDailyCompoundInterestByEod→AccrueCompoundEod + 全链路Trace
- AccrualTrace新增Segment(分段区间/天数/基数/利率)与EodContext(重置日/平仓比例/基数分量)语义方法
- AccrueSimplePeriod/AccrueCompoundPeriod补全AccrualTrace?参数:MarkStart→逐段Segment→复利Rollover→Unwind→MarkEnd
- CalcDailyCompoundInterestByEod内部实现下沉至FundingLegAccrual.AccrueCompoundEod纯函数
  删除调试垃圾LogFactory('test').Error,取率/重置日/remainingFraction逻辑保留
- flowEvent.InterestPrincipal/FloatRate副作用在调用方保留(下游EOD播种次日TdInterestPrincipal)
- 全量SwapModule测试零回归(7基线失败/508通过/8跳过)
2026-08-12 10:37:52 +08:00
hjhan 2f7caa7a1f refactor(accrual): referenceNotional→baseNotional, notional统一
- referenceNotional → baseNotional(更短更清晰)
- 新代码统一用 notional(不用 principal):
  QuantLib/Strata 对 swap leg 用 notional 是业界标准
- DB字段(InterestPrincipalFix等)保持不动(legacy)
- 注释标注 legacy 对照(orginPv/originalPv/dynomicPrincipal)

验证: 编译0错误, 7影子测试全过, 全量523测试7失败(基线一致)。
2026-08-12 10:20:13 +08:00
hjhan ce6c0812e1 refactor(accrual): 参数命名对齐业界标准(QuantLib/Strata)
FundingLegAccrual 4个方法的参数命名全面纠正:

| 旧名              | 新名               | 理由 |
|-------------------|-------------------|------|
| originalPv        | referenceNotional | Pv(现值)概念错误,实际是参考本金 |
| closeRatio/closePercent | unwindFraction | 统一,对齐 ApplyUnwind.unwindPercent |
| consumedInterest  | realizedInterest  | 对齐 AccrualState.RealizedInterest |
| priorUnrealized   | priorAccrued      | 对齐 InterestResult.Accrued |
| priorAccrualPrincipal | priorNotional  | 简洁,对齐 QuantLib notional |
| positionPrincipal | notional          | 简化,去掉冗余前缀 |
| dynomicPrincipal  | accrualBasis      | 修正typo+用业界术语 |

同步更新:
- SwapDealService.CalcDailySimpleInterestByEod 调用点
- 3个影子测试文件命名参数
- SwapInterest.Round 改为 public(所有Round收口一处)

删除半成品残留: SwapInterest_CompoundInArrears_RolloverTimingTests.cs

验证: 编译0错误, 7个影子测试全过, 全量520测试7失败(基线一致)。
2026-08-12 10:11:26 +08:00
hjhan 3f194f7ccc fix(accrual): Round收口到SwapInterest.Round + 复利分段边界修复
3项修复:

1. SwapInterest.Round 从 private 改为 public:
   所有计息路径收口到一处, FundingLegAccrual 不再用裸 Math.Round

2. ApplyUnwind 精度警告:
   注释标注'资金腿务必传 FundingLegPrecision=12', 默认11是易忘的坑

3. AccrueCompoundPeriod 分段边界修复(根因):
   旧bug: 中间段 IncludeEnd=true 导致重置日利息用了旧本金
   修复: 中间段 IncludeEnd=false(半开区间), 重置日归下一段用新本金
   对齐旧逐日循环语义: 重置日先更新本金再算息

同时: 中间值不Round(对齐旧代码只在最终输出Round一次)
清理: 删除 SwapInterestAccrueCompoundInArrearsTest 半成品残留

验证: 编译0错误, 7个影子测试全过, 全量520测试7失败(基线一致)。
2026-08-12 09:59:53 +08:00
hjhan 552fb2061b Merge branch 'glms/feature/1.4.2' of http://git.yiliantech.com/gitlab/otc-dev/zszq-trs into glms/feature/1.4.2 2026-08-12 09:48:53 +08:00
hjhan 431ac9b502 feat(accrual): 新增 AccrueCompoundPeriod + 影子测试(3个全过)
第3步迁移: CalcDailyCompoundInterest(盘中复利多日)。

新增纯函数 AccrueCompoundPeriod:
- 从 PosiStartDate 到 endDate 全程重放
- 每个重置日并本金: principal + replayed interest
- 末日(endDate)为重置日且 resetCarryInterest!=0 时用存量替代
- consumedInterest × closePercent 在末尾扣除
- 分段模型替代逐日循环, 段内本金恒定+利率恒定

影子测试(3个,全过):
- 固定利率全平+末日重置日: 旧新一致
- 部分平仓30%+consumedInterest扣除: 旧新一致
- 算头算尾(calcMode=11): 旧新一致

清理: 删除 SwapInterestAccrueCompoundInArrearsTest(半成品残留,
依赖已回退的 SwapInterest 签名)。
修复: SwapInterestAccrueCompoundInArrearsTest 缺 using(已随文件删除)。

验证: 编译0错误, 全量520测试7失败(基线一致)。
4个CalcDaily*方法的新架构纯函数全部就绪, 旧方法暂保留对比。
2026-08-12 09:48:49 +08:00
张名锐 225e0e3e80 Merge remote-tracking branch 'origin/glms/feature/1.4.2' into glms/feature/1.4.2 2026-08-12 09:45:19 +08:00
张名锐 ec820a4974 Merge branch 'glms/feature/1.4.2_0808' into glms/feature/1.4.2 2026-08-12 09:44:51 +08:00
hjhan 963b5e66af feat(accrual): 新增 AccrueSimplePeriod + 影子测试
第2步迁移: CalcDailySimpleInterest(盘中单利多日)。

新增纯函数 AccrueSimplePeriod:
- 单利特征: 计息本金恒定(差分 = priorAccrualPrincipal + positionPrincipal - originalPv)
- 按重置日分段, 每段用 AccrualDays 算天数×日利息(无逐日循环)
- 续接 priorValueDate 之后的日期

修复: SwapInterest.Round 是 private, 新方法改用 Math.Round。
修复: IReadOnlyList 无 IndexOf, 改用 for 循环索引。

影子测试(2个,全过):
- 固定利率无归档: 旧新一致(差分本金=0,利息=0,符合旧逻辑)
- 有归档续接+部分平仓50%: 旧新一致

验证: 编译0错误, 全量517测试7失败(基线一致)。
2026-08-12 09:27:20 +08:00
hjhan 217c2d5826 feat(accrual): 新增 FundingLegAccrual.AccrueCompoundEod + 影子测试
第1步迁移: CalcDailyCompoundInterestByEod(EOD复利单日)。

新增纯函数 AccrueCompoundEod:
- 重置日: 本金 = positionPrincipal + priorUnrealized × remainingPercent
- 非重置日: 本金 = priorAccrualPrincipal + positionPrincipal - originalPv
- InterestAmount = priorUnrealized × closeRatio + dayInterest
- TdInterestAmount = dayInterest(不含 priorUnrealized)

影子测试(2个,全过):
- 重置日场景: 旧新 InterestAmount/TdInterestAmount 一致
- 非重置日场景: 同上

旧方法暂不删——新旧并存,对比验证后再替换调用点。
验证: 编译0错误, 全量515测试7失败(基线一致)。
2026-08-12 09:15:01 +08:00
hjhan 5dc8bdbf9e refactor(interest): 计息 trace 命名对齐业界最佳实践
- InterestTrace → AccrualTrace:追踪对象是"计息过程"而非泛指的 Interest,与仓库
  既有的 SwapCalcTrace(-Trace 后缀约定) 及 AccrualContext/AccrualBoundary/AccrualPolicy
  家族一致;AccrualTrace 经 SwapCalcTrace.Write 常驻落盘,二者职责分清(收集器 vs 落盘通道)。
- InterestStep → AccrualTraceEvent、InterestTraceEntry → AccrualTraceEntry:
  条目类别对应 QuantLib/Strata 的"事件"概念(AccrualTraceEvent),命名自描述。
- SwapCalcTrace.Persist → Write:"Persist" 易误读为落库持久化;此处只是写入日志通道,
  且类内已有私有 Record(string),故用 Write 避免歧义。

纯改名、数值逻辑零改动;YLErpDAL + UnitTestProject 编译 0 错。
2026-08-12 07:05:41 +08:00
hjhan be3be877ec refactor(interest): 引入 AccrualContext 并将 AccrueCompound 重命名为 AccrueCompoundInArrears
1. 新增 AccrualContext 只读值对象,把 annualDays/precision/trace 三个"与金额利率无关"
   的横向参数打包为上下文成员。计息纯函数只吃一个 ctx,签名去噪、可读性提升;
   ctx 为只读值对象(非类的实例/静态字段),不破坏纯函数(线程安全、可重入、可测)。
   trace 因此成为"传入上下文的成员"而非散落参数,满足"默认成员而非参数"的诉求。

2. AccrueCompound → AccrueCompoundInArrears:精确表达 OIS/SOFR/FR007 的
   compounded-in-arrears 语义(每子区间取定盘、段末滚入本金),与
   InterestRate.Compounding.Compounded 闭式分支(TRS 下死路径)一刀两断、不再混淆。

纯增量、数值逻辑不变;YLErpDAL + UnitTestProject 编译 0 错 0 警;FR007 两段切换场景
实跑 trace 与旧版数值完全一致。
2026-08-12 06:13:38 +08:00
hjhan fcf52a305e feat(interest): 融资腿计息接入 trace 并常驻落盘
FundingLegAccrual.AccrueSimpleEod 接 InterestTrace;SwapCalcTrace 新增 Persist
把收集器条目经 Critical 无条件落盘(与开关无关);已迁移的 EOD 单利适配器
CalcDailySimpleInterestByEod 创建并 Persist trace。纯增量、数值逻辑不变。
2026-08-12 06:05:02 +08:00
hjhan fba87bd7cc feat(interest): AccrueCompound 支持每段独立利率 + 发射 Reset/Rollover trace
重构为按重置日切段、每段可有独立利率(resetSchedule),适配 FR007 浮动逐段取价
(取价仍在编排层,原语只吃一个数,与 QuantLib/Strata 同范);trace 记录
重置日前后利率切换与段末并本金(本金增加),完整覆盖"重置日前后/利率切换/本金增减"。
2026-08-12 06:05:02 +08:00
hjhan 03861ea369 feat(interest): 新增 InterestTrace 结构化追踪收集器
纯值对象(零日志依赖):计息纯函数把"发生了什么"记录为语义化条目
(Day/ResetBefore/ResetAfter/Rollover/Unwind),由适配器统一经 SwapCalcTrace
常驻落盘。ToString 产出稳定可 diff 的逐行文本,新旧引擎同一笔交易可直接 diff
定位"是计算变了还是重构引入漂移"。
2026-08-12 06:05:01 +08:00
hjhan 63bfc8ca8f refactor(interest): SwapDealService 接入 FundingLegRate 工厂并复用 FundingLegPrecision
取率处改用 Fixed/Floating 工厂;InterestCalculationPrecision 引用
SwapInterest.FundingLegPrecision,消除重复常量定义。
2026-08-12 05:36:02 +08:00
hjhan dee491b8d0 refactor(interest): FundingLegAccrual 删除危险骨架,仅保留纯函数 AccrueSimpleEod
移除标注"切勿在未迁移前接入生产"的 AccrueDay/AccruePeriod 骨架(含 IIndexFixer/
Func 取价),保留与旧实现逐字对齐的纯函数,消除两套计息逻辑并存的隐患。
2026-08-12 05:36:02 +08:00
hjhan e7514a2d84 cleanup(interest): 删除 AccrualPolicy 未使用的 FromLegacy 工厂与冗余 using
FromLegacy 无调用方;移除 YLErp.DBModels using 后 InterestTypeEnum 仅存于注释。
2026-08-12 05:36:02 +08:00
hjhan 4e67af52e8 refactor(interest): FundingLegRate 瘦身为单一 all-in 利率值对象
固定/浮动腿的区别是取率环节的事,计息只认一个数;以 Fixed/Floating 工厂
取代原 4 字段构造,不再为腿型背负多余字段。
2026-08-12 05:36:01 +08:00
hjhan 39ec71f268 refactor(interest): SwapInterest 计息数学收敛为 InterestRate,新增资金腿精度常量
引入 ToInterestRate 入口把 TRS 利率收敛为通用原语;提取 FundingLegPrecision=12
公共常量,消除 SwapDealService 与 FundingLegAccrual 的重复定义。
2026-08-12 05:36:01 +08:00
hjhan aff540801c feat(interest): 新增通用利息原语 InterestRate(与互换解耦)
单利/复利/连续复利收敛为 Compounding 一个 switch 分支,利息计算不再住在
SwapModule/互换词汇里,谁需要算息都能直接用。连续复利仅 e^(r·t) 一行。
2026-08-12 05:36:01 +08:00
hjhan 0c447ff5ff refactor: 提取融资腿计息领域模型 (AccrualPolicy/FundingLegRate/AccrualState/FundingLegAccrual) - 将 CalcDailySimpleInterestByEod 纯数学下沉至 FundingLegAccrual.AccrueSimpleEod, 消除 double 往返转换, 引入值对象收敛散落参数 2026-08-11 22:37:19 +08:00
hjhan 246392b665 cleanup: 删除 SwapInterestAdapter 半成品, 回退 SwapInterest 未提交改动
SwapInterestAdapter + SwapInterest 增强(annualized/segmentRates/
resetCarryInterest) + 配套测试 是半成品, 有G7/G8已知边界,
且破坏现有测试。按审查建议回退, 作为独立PR后续处理。

当前工作区只剩 BondIndex/RateYield 到期日修复。
验证: 编译0错误, 全量513测试7失败(基线一致)。
2026-08-11 19:23:21 +08:00
lisong f49fc7f8c2 Merge remote-tracking branch 'dest/glms/feature/1.4.2' into glms/feature/1.4.2_0808 2026-08-11 18:23:14 +08:00
尹峰 30b3007307 !24 !23 feature/p132_74-risk-engine 风控引擎二期
Merge pull request !24 from glms/feature/1.4.2
2026-08-11 09:41:36 +00:00
hjhan dafc06793e refactor: AddClientCashInCashOut 加 virtual + 修正架构文档
AddClientCashInCashOut 从 public 改为 public virtual,
使测试可 override, 消除 RecordMarginCashFlow 迁出的阻塞。
AddClientCash 已是 virtual, 这是统一两者。

修正 ARCHITECTURE.md: 保证金有余额和返息(非'没有计息基数')。

验证: 编译0错误, 全量513测试7失败(基线一致)。
2026-08-11 17:09:13 +08:00
hjhan 7cea09d976 docs: 新增 SwapModule ARCHITECTURE.md 架构说明
记录重构后的三大限界上下文结构:
- FundingLegs(融资腿) / Margin(保证金) / ReturnLegs(标的端)
- 命名规则(防歧义): Funding/Return/Margin/FloatRate
- Core 层纯函数库(SwapInterest + IIndexFixer)
- 已消除的 inline 重复清单
- 方向因子类型规范(int)
- 待后续改造的接缝预留

不改原有文档(corp-action-*.md 仍准确)。
2026-08-11 17:03:44 +08:00
hjhan 5a7869e0c9 fix(return-leg): PositionValueCalc.ratio 改为 int, 统一方向因子类型
ratio(收取=1/支付=-1)是方向因子, 应该是 int。
和 MtmCalc/DirectionRatio/MarginCalc 的 int 保持一致。

调用点(SwapEodPositionService 4处)原 ratio 是 decimal,
加 (int) 显式转换(值恒为 1或-1, 零精度损失)。

排查确认: 这是唯一的类型不一致, 其他纯函数参数类型均已统一。
验证: 编译0错误, 全量513测试7失败(基线一致)。
2026-08-11 16:59:22 +08:00
hjhan 16c44d3b50 refactor(return-leg): 抽取 PositionValueCalc 持仓价值汇总
SwapEodPositionService 8处 SwapPositionValue inline 公式替换:
- 4处 InterestProfitSum * ratio + PosiProfitSum → PositionValueCalc.Calc(带ratio)
- 4处 InterestProfitSum + PosiProfitSum → PositionValueCalc.Calc(默认ratio=1)

持仓价值 = 利息端收益 + 浮动端收益, 8处副本→1个纯函数。
这是最后一个高性价比的纯函数提取。

验证: 编译0错误, 全量513测试7失败(基线一致)。
2026-08-11 16:50:21 +08:00
hjhan 744f1ae448 Merge branch 'glms/feature/1.4.2' of http://git.yiliantech.com/gitlab/otc-dev/zszq-trs into glms/feature/1.4.2 2026-08-11 15:46:35 +08:00
hjhan 7e169dd53f fix(margin): 回退 PreviousBalance 简化, 恢复三级 fallback
尝试去掉第2级(TdInterestPrincipal)导致5个保证金测试失败。
根因: 生产 EOD 归档(eod_swap_position(35774))的 InterestPrincipalFix=0,
只有 TdInterestPrincipal 有值。第2级不是死代码, 不可删。

恢复三级 fallback, 补充注释说明每级命中的真实场景。
教训: 不能只看赋值点判断字段是否有值, 必须看实际数据。
验证: 编译0错误, 全量509测试7失败(基线一致)。
2026-08-11 15:46:28 +08:00
tengyufan 83553a4e55 Merge remote-tracking branch 'origin/glms/feature/1.4.2' into glms/feature/1.4.2 2026-08-11 14:35:57 +08:00
tengyufan 937884dca6 Merge remote-tracking branch 'origin/glms/feature/1.4.2' into glms/feature/1.4.2 2026-08-11 14:35:46 +08:00
hjhan 6fe5d81917 refactor(margin): 3个保证金纯函数迁入 MarginCalc, 改正命名
从 SwapDealService 剥离到 Margin/MarginCalc.cs:
- PreviousBalance: 取上一日终保证金余额(原 ResolveMarginOrginPv, 改正命名)
- FlipDirection: 保证金方向翻转(原 FlipMarginDirection)
- AccumulateSettlement: 平仓汇总(原 AccumulateMarginSettlement)

命名修正: orginPv 是融资腿概念, 保证金没有; 改为 PreviousBalance。
SwapDealService 里删掉这3个private方法, 调用点改用 MarginCalc.XXX。
RecordMarginCashFlow 暂留(依赖实例方法 AddClientCash)。

保证金纯函数现在全部在 Margin 模块, SwapDealService 只保留
RecordMarginCashFlow(资金记录, 需要实例上下文)。
验证: 编译0错误, 全量509测试7失败(基线一致)。
2026-08-11 14:35:42 +08:00
tengyufan fcf94ce982 fix: 去除非国联客户审批配置case 2026-08-11 14:35:34 +08:00
hjhan 2fbffcceb4 refactor(margin): 3处散落保证金资金记录收敛到 RecordMarginCashFlow
RecordMarginCashFlow 加委托重载, 统一 AddClientCash(virtual)和
AddClientCashInCashOut(非virtual)两条路径。

替换3处 inline:
- :1663 SwapUnwind 平仓(AddClientCash, 只有应付预付金)
- :1979 DealUnwind(AddClientCashInCashOut, 只有应付预付金)
- :2128 SwapIncome 互换(AddClientCash, 只有预付金返息)
- :2195 自动互换(AddClientCash, 只有应付预付金, swapEvent.unwindData)

注释掉的返息代码(//if SwapMarginRebatePnl)同步清理——
通过传 marginRebate:0 表达'不写返息', 不再留注释代码。

SwapDealService 保证金资金记录 inline: 4处 → 0。
全部走 RecordMarginCashFlow 的 2 个重载。
验证: 编译0错误, 全量509测试7失败(基线一致)。
2026-08-11 14:26:29 +08:00