hjhan
|
d61ff742de
|
refactor(return-leg): SwapDealService 增值税公式替换为 DividendCalc
SwapDealService:1806 inline 的 dividendIn/(1+tax)*(1-tax) 替换为
DividendCalc.AfterTaxRaw(中间计算不四舍五入)。
全库 payment/(1+tax)*(1-tax) inline 公式: 5处(SwapEod 4 + SwapDeal 1) → 0。
全部收敛到 DividendCalc.AfterTax / AfterTaxRaw。
验证: 编译0错误, 全量507测试7失败(基线一致)。
|
2026-08-11 11:18:56 +08:00 |
|
hjhan
|
c52d439469
|
refactor(return-leg): 4处增值税inline公式替换为 DividendCalc
SwapEodPositionService 4处 payment/(1+tax)*(1-tax) inline 替换:
- 1804/1906/2094: Math.Round(...) → DividendCalc.AfterTax(payment, tax)
- 1893: 中间计算(不四舍五入) → DividendCalc.AfterTaxRaw(total, tax)
修复 MtmCalcTest: UnrealizedPnl 第6参数 ratio 从 1m 改为 1(int)。
(1+tax) inline 公式出现次数: 4 → 0。
验证: 编译0错误, 全量507测试7失败(基线一致)。
|
2026-08-11 11:12:15 +08:00 |
|
hjhan
|
939d6a4271
|
fix(return-leg): MtmCalc.UnrealizedPnl ratio 参数改为 int
ratio(收取=1/支付=-1)和 shortRatio 一样是 int, 不是 decimal。
1695行 ratio 声明同步从 decimal 改为 int。
C# decimal*int 自动提升为 decimal, 不影响计算结果。
验证: 编译0错误, 全量507测试7失败(基线一致)。
|
2026-08-11 11:05:55 +08:00 |
|
hjhan
|
963f7a04e5
|
refactor(return-leg): 新增 DividendCalc 分红增值税后计算 + 修复 MtmCalc 参数类型
DividendCalc: 增值税后票息 = payment/(1+tax)*(1-tax),
原 SwapEodPositionService 4处重复此公式(1804/1894/1906/2095)。
本次先建纯函数+测试, 4处inline替换下次做。
附带修复: MtmCalc shortRatio 参数从 decimal 改为 int
(原代码6处声明中5处是int, 仅1696是decimal, 统一为int)。
1696行 shortRatio 声明同步改为 int。
验证: 编译0错误, DividendCalc 4个测试全过,
全量507测试7失败(基线一致)。
|
2026-08-11 11:04:08 +08:00 |
|
hjhan
|
946cbbb66d
|
refactor: InterestLeg 改名 FundingLeg(业界标准 Financing Leg)
命名: InterestLeg→FundingLeg, 消除'interest'与通用'利息'歧义。
Funding精确表达'融资成本'(客户付券商的杠杆成本 spread+FR007)。
改名清单:
- IInterestLegStrategy → IFundingLegStrategy
- InterestLegStrategyFactory → FundingLegStrategyFactory
- InterestLegStrategyTest → FundingLegStrategyTest
- 命名空间 InterestLegs → FundingLegs
- 目录 InterestLegs/ → FundingLegs/
- SwapDealService 引用同步更新
验证: 编译0错误, 全量503测试7失败(基线一致)。
|
2026-08-11 10:52:04 +08:00 |
|
hjhan
|
a26f848287
|
refactor(return-leg): 抽取 MtmCalc 标的端盯市计算
把 SwapEodPositionService 4处重复的 UnderlyingMarketValue 公式和
4处 PosiMtmPnL 公式抽成 MtmCalc 纯函数:
- MarketValue(price, qty, contractSize, shortRatio): 标的市值
- UnrealizedPnl(price, costGrossPrice, qty, contractSize, shortRatio, ratio): 盯市未实现盈亏
原代码4处副本(1731/1813/1898/2101 + 1741/1814/1899/2102)全部替换。
验证: 编译0错误, 全量503测试7失败(基线一致)。
|
2026-08-11 10:45:43 +08:00 |
|
hjhan
|
59651b802e
|
refactor(return-leg): QuantityRollforward 改名 QtyRollforward
代码里统一用 Qty 表示数量, 命名更简洁。
文件/类/测试类同步改名: Quantity→Qty。
|
2026-08-11 10:40:17 +08:00 |
|
hjhan
|
279c640345
|
refactor(return-leg): 抽取 QuantityRollforward 标的端数量递推
把 SwapEodPositionService:1980 inline 的数量递推公式抽成独立纯函数:
qty = 上一日终数量 + 开仓 - 平仓 + 公司行为调整
新增第4参数 corpActionDeltaQty(默认0,当前不影响行为),
预留给公司行为改造(送股/拆股/配股)。
原代码硬编码'数量只因交易变动'假设,改造时填入非零值即可。
ReturnLegs/QuantityRollforward.cs: 纯函数, 不依赖任何实例状态
ReturnLegs 测试: 8个(无交易/开仓/平仓/全平/超额/送股/拆股)
SwapEodPositionService: inline 2行 → QuantityRollforward.Calc() 1行
验证: 编译0错误, 全量497测试7失败(基线一致)。
|
2026-08-11 10:36:38 +08:00 |
|
hjhan
|
82fb5e5916
|
refactor(margin): SwapDealService 5处保证金判断收敛到 MarginModes
把 5 处 inline 的 InterestModeEnum==5||6 判断改为 MarginModes.Contains:
- :99 前端参考计算分流(MarginLegs vs InterestLegs)
- :680 ResolveInterestLegPositions 持仓对齐
- :716 ResolveInterestLegPositionsAsOf 未来持仓 LINQ Where
- :722 ResolveInterestLegPositionsAsOf if 判断
- :2023 平仓 SwapMarginAmount 汇总
- :2441 UpdateInitalPosition 平仓递减
仅剩 CalcNotionalByMode 的 case 标签(switch case 须常量,无法用 Contains)。
SwapDealService 内 InterestModeEnum.初始预付金/追加预付金 引用: 10处→2处(case标签)。
验证: 编译0错误, 全量489测试7失败(基线一致)。
|
2026-08-11 10:30:44 +08:00 |
|
hjhan
|
a868f3eb15
|
refactor(margin): 抽取 FlipMarginDirection 保证金方向翻转方法
2处 inline 的保证金方向翻转(收取↔支付)抽成独立方法 FlipMarginDirection。
保证金利息是券商付给客户, 方向与融资腿相反。
- GetInterests 路径(854行): if(5||6) → MarginModes.Contains + FlipMarginDirection
- 衡泰路径(1934行): 同上, 保留 _closePosiNotionalValue=0
判断从 InterestModeEnum==5||6 改为 MarginModes.Contains(统一口径)。
纯提取, 行为零变化。
验证: 编译0错误, 全量489测试7失败(基线一致)。
|
2026-08-11 10:27:18 +08:00 |
|
hjhan
|
ae4af111f3
|
refactor(margin): 抽取 ResolveMarginOrginPv 保证金维度重映射方法
把 InitSwapDealInterest 里 8 行 inline 的 orginPv 重映射逻辑抽成独立方法
ResolveMarginOrginPv(position, preEodPosition, fallback)。
保证金腿被迫走融资腿差分公式(dynomicPrincipal = TdPrincipal + posi - orginPv),
但 orginPv 对融资腿是'交易名义本金',对保证金腿须对齐到'保证金余额',
否则维度不匹配算出巨负值。提取后 InitSwapDealInterest 更干净,
且新方法待迁入 Margin 模块。
判断从 InterestModeEnum==5||6 改为 MarginModes.Contains(统一口径)。
纯提取, 行为零变化。
验证: 编译0错误, 全量489测试7失败(基线一致)。
|
2026-08-11 10:23:22 +08:00 |
|
hjhan
|
e73272042a
|
refactor(return-leg): 新增 ReturnLegSummary 标的端值对象
标的端(Total Return Leg)归档产出的汇总值: 多空名义本金/平仓名义本金/含费全价。
对应原 SwapPositionCompose 里 DealFloatPositions 传给 DealInterests 的4个标量。
命名说明(防歧义):
- 用 ReturnLeg(业界标准 Total Return Leg), 不用 FloatLeg
- 'float'在金融里首要含义是'浮动利率'(如FR007), 用于标的端会产生歧义
- 标的端 = 标的资产的总回报(价格涨跌+票息分红), 与浮动利率无关
纯新增骨架, 零生产改动。
验证: 编译0错误, 3个单测全过, 全量489测试7失败(基线一致)。
|
2026-08-11 10:15:20 +08:00 |
|
hjhan
|
b7469be104
|
refactor(margin): 保证金去除'计息基数'错误概念, 改用余额建模
保证金就是保证金——有余额、有利率、有利息, 不存在'计息基数/Notional'概念。
现有代码把保证金塞进 InterestPrincipalFix 当计息腿处理是错误建模。
修正:
- 删除 MarginLeg.cs(CalcBalance/accrualFactor 是融资腿的概念, 不该用在保证金)
- 新增 MarginAccount.cs: 管理余额变动(Deposit追加/Withdraw释放), 不含计息
- MarginBalance: 注释去掉'计息基数', 改为'保证金余额'
- IMarginResolver.Resolve: 去掉 accrualFactor 参数(融资腿比例, 非保证金概念)
- CashMargin/CreditMargin/GuaranteeMargin: 同步去掉 accrualFactor
- 枚举注释: '计息余额' → '余额'
保证金利息由 SwapInterest 纯函数按 余额×利率×天数/年化 计算,
MarginAccount 只提供余额, 不掺计息逻辑。
验证: sln编译0错误, 全量486测试7失败(基线一致,零回归)。
|
2026-08-11 10:06:27 +08:00 |
|
hjhan
|
22f22bc9c5
|
refactor(margin): ConsTrade.InterestMarginModels 4处引用收敛到 MarginModes
上次失败根因: EodClientBalanceCalc:134 是 EF Core LINQ 表达式,
HashSet.Contains 无法翻译成 SQL, 导致场景3/4 全红。
修正: MarginModes 新增 ForLinq(List<int>) 供 EF Core 翻译用。
- SwapEodPositionService 2处纯函数(非LINQ): 用 MarginModes.Contains
- EodClientBalanceCalc LINQ表达式: 用 MarginModes.ForLinq.Contains
- RealTimeClientBanlanceService(已ToList,内存集合): 用 MarginModes.Contains
ConsTrade.InterestMarginModels 产品代码引用: 4处 → 0(只剩定义+注释)。
保证金mode判断 {初始预付金,追加预付金} 现在统一由 MarginModes 提供。
验证: sln编译0错误, 全量485测试7失败(基线一致,零回归)。
|
2026-08-11 09:57:20 +08:00 |
|
hjhan
|
ef1a126b8f
|
refactor(margin): 4处散落marginTypes收敛到MarginModes
SwapEodPositionService: 删除 marginTypes 字段(13处.Contains全改MarginModes.Contains)
SwapEventEmailService: marginTypes 字段改为 MarginModes.All.ToList()
EodClientBalanceCalc: 删除未使用的 marginTypes 局部变量(死代码)
ClientBalanceUtility: 删除未使用的 marginTypes 局部变量(死代码)
收敛后 {初始预付金,追加预付金} 集合只在 MarginModes.All 一处定义,
消除6处副本口径分裂风险。
验证: sln编译0错误, 全量485测试7失败(基线一致,零回归)。
注: 上次27失败是stash残留导致的状态不一致,本次从干净状态逐步改。
|
2026-08-11 09:40:48 +08:00 |
|
hjhan
|
553e3d4c6d
|
refactor(margin): 新增 MarginModes 统一保证金mode判断口径
现状: 同一集合{初始预付金,追加预付金}在代码里复制了至少6次
(ConsTrade.InterestMarginModels + 5处局部marginTypes/premiumModes)。
任何一处漏改(如新增保证金形态)都会导致口径分裂。
本次: Margin 模块新增 MarginModes 静态类, 作为单一判断来源。
- IReadOnlyCollection<int> All: 保证金mode集合
- bool Contains(int): 判断mode是否属于保证金
后续逐个替换散落的marginTypes/premiumModes/InterestMarginModels。
纯新增, 零生产代码改动。
验证: 5个单测全过, 全量485测试7失败(基线一致)。
|
2026-08-11 09:27:25 +08:00 |
|
hjhan
|
30ae93b8ca
|
fix(interest): SwapDealIndexFixer 改用委托, 修复 CS0122 编译错误
问题: SwapDealIndexFixer(internal)访问 SwapDealService.TryGetFloatRate
(protected) 报 CS0122, 因非嵌套类无权访问 protected 成员。
修复: SwapDealIndexFixer 改为接受 Func<DateTime,string,(bool,double)> 委托,
SwapDealService.IndexFixer 属性传入 TryGetFloatRate 的包装。
- 无需访问 protected 成员
- SwapDealIndexFixer 保持独立文件(clean code)
- virtual 接缝仍保留(测试 override TryGetFloatRate 仍生效)
验证: YLErpDAL.csproj 编译 0 错误, 全量480测试7失败(基线一致,零回归),
CI_007/CI_008 通过。
|
2026-08-11 09:23:01 +08:00 |
|
hjhan
|
59c16aabc1
|
refactor(interest): SwapDealService 6处取价收敛到 IIndexFixer
修正上次尝试的失败: 静态 Fr007IndexFixer.Instance 绕过了
TryGetFloatRate(virtual)接缝, 导致测试 stub 失效(CI_007/CI_008失败)。
本次方案: 新增 SwapDealIndexFixer(实例级, 委托 TryGetFloatRate):
- SwapDealService.IndexFixer 属性 lazy 初始化, 包 SwapDealIndexFixer
- 6处 GetNonHolidayDefore+TryGetFloatRate 全部替换为 IndexFixerBase+IndexFixer
- TryGetFloatRate(protected virtual)保留不动, 测试 stub 机制完全不受影响
验证: CI_007/CI_008 从失败转为通过, 全量480测试7失败(与基线一致,零回归)。
SwapDealService 内 GetNonHolidayDefore 出现次数: 6 → 0(全部收敛到 IndexFixerBase)。
|
2026-08-11 09:17:42 +08:00 |
|
hjhan
|
7d0397fc44
|
refactor(interest): CalcNotionalByMode 融资腿委托策略工厂
融资腿(mode 1固定值/2合约名义本金/9标的期初全价)改由
InterestLegStrategyFactory.Get(mode).CalcNotional(...) 计算,
不再走原 switch 的 case。
保证金(mode 5/6)和多空存续(mode 7/8)暂保留原 switch 逻辑,
待 Margin 上下文接入后再迁出。
行为等价: 全量480测试, 改动前后失败数一致(7个, 全为无库环境问题),
零回归。
|
2026-08-11 09:13:26 +08:00 |
|
hjhan
|
55284fb76b
|
refactor(margin): 抽出独立 Margin 限界上下文,移除 PrepayLeg 错误继承
- 新建 YLErp.Modules.SwapModule.Margin:MarginBalance / MarginLeg / IMarginResolver(Cash/Credit/Guarantee)
- MarginLeg 不继承 IInterestLegStrategy,与利息腿完全解耦(保证金是客户存款/担保,非互换腿)
- 删除 PrepayLeg,工厂不再注册 mode 5/6 预付金
- 预付金用例迁入 MarginLegTest,旧 InterestLegStrategyTest 改为断言预付金已非利息腿
|
2026-08-10 22:09:09 +08:00 |
|
hjhan
|
aca834d8dc
|
refactor(interest): 新增预付金腿策略 + 策略工厂
新增(零生产改动):
- InterestLegs/PrepayLeg.cs
mode 5 初始预付金 / mode 6 追加预付金 共用。
计息基数=InterestPrincipalFix, 平仓本金=Fix×closePercent。
构造时校验mode合法性(只接受5/6)。
方向翻转/orginPv重映射等独有逻辑后续单独抽。
- InterestLegs/InterestLegStrategyFactory.cs
按InterestMode返回对应策略, 收敛switch分发。
死代码mode 3/4/7/8不注册, 传入会抛ArgumentException。
测试(14个全过):
- 预付金: 部分平仓/全平/非法mode构造
- 工厂: 各活跃mode返回正确类型/未注册mode抛异常/int重载等价
fixing接入尝试(已回退):
- 尝试用Fr007IndexFixer.Instance替换SwapDealService的6处取价
- 发现问题: 静态Instance绕过TryGetFloatRate(virtual)接缝,
破坏测试stub机制(CI_007/CI_008失败)
- 已回退, 下次改用实例级IIndexFixer(委托TryGetFloatRate)方式接入
|
2026-08-10 18:40:04 +08:00 |
|
hjhan
|
79e9304114
|
refactor(interest): 新增利息腿策略接口 + 3个活跃mode实现
为拆三类腿做准备,按 Strategy 模式封装 CalcNotionalByMode 的 switch。
本次零生产代码改动,全部为新增小文件,每个类单一职责<50行。
新增(策略接口+值对象):
- InterestLegs/IInterestLegStrategy.cs
NotionalResult 值对象(closePrincipal/posiPrincipal/closePercent)
+ IInterestLegStrategy 接口(每个mode一个实现)
新增(3个活跃利息腿mode):
- InterestLegs/FixedNotionalLeg.cs mode 1 固定值
计息基数恒=InterestPrincipalFix, 不随平仓比例变化(合同写死的固定值)
- InterestLegs/ContractNotionalLeg.cs mode 2 合约名义本金规模
平仓本金=posiNotional×closePercent, 按比例线性缩放
- InterestLegs/UnderlyingFullPriceLeg.cs mode 9 标的期初全价
主路径公式同mode2, 差异在衡泰路径grossPrice折算+EOD复利反推
确认现状:
- 界面实际只有3个活跃利息腿mode(1/2/9), TradeView.cshtml:330-349
- mode 3(持仓名义本金)/4(持仓市值) 零引用=死代码, 本次不实现
- mode 7/8(多空存续) 界面已注释掉, 本次不实现
- mode 5/6(预付金) 属保证金维度, 后续单独做PrepayLeg
新增测试(8个,全过):
- InterestLegStrategyTest.cs 覆盖各mode的部分平仓/全平/零平仓场景
验证策略行为与现有CalcNotionalByMode switch完全一致
|
2026-08-10 18:32:17 +08:00 |
|
hjhan
|
a0bca2858f
|
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-10 18:02:01 +08:00 |
|
hjhan
|
250c41b925
|
refactor(interest): 抽取 IIndexFixer 取价接缝 + 清理固定值腿错误测试
为后续拆三类腿做准备,新增 FR007 取价的独立接口层(参考 QuantLib IborIndex
分层),本次零生产代码改动,全部为新增小文件。
新增文件(取价接缝,供后续 SwapDealService 6 处 inline 取价迁移用):
- Framework/YLErp.Core/Interest/IIndexFixer.cs
接口定义:给定取价日和标的代码返回当日利率,取价与计息解耦
- Framework/YLErp.Core/Interest/IndexFixerBase.cs
取价日计算工具:收敛原散落 6 处的 GetNonHolidayDefore(date.AddDays(rule))
- YLErpDAL/Modules/SwapModule/Fr007IndexFixer.cs
生产实现 + GetFixingOrThrow 辅助方法,独立文件便于单测
测试清理(删除基于错误假设的测试):
- 删除 SwapFixedInterestLegClosePercentBugTest.cs 整个文件
该文件假设'固定值腿利息应随平仓比例线性缩放',但固定值是合同写死的、
永远不随平仓比例变化。d1badfe4 的'修复'本身才是错的,当前分支已正确回退
- 修正 SwapUnwindPrepayPrincipalBugTdd.cs 固定值测试方法
断言从'应=Fix×0.5'改为'恒=Fix不随比例变化',对齐正确的业务定义
已知失败(非本次引入,留待后续与拆腿一起修):
- BondTrsAutoSwapScenarioTest 的 AS_001/004/008/009/010/011 共 6 个
原因:SaveAutoSwapDeal 直接调 AddClientCashInCashOut(非virtual)绕过
AddClientCash(virtual)封装,无库环境抛'客户信息未找到'。
从 096d2609 引入时即失败,需 AddClientCashInCashOut 加 virtual + 客户数据
mock,与拆腿那次可测性改造一起做
|
2026-08-10 18:01:37 +08:00 |
|
张名锐
|
8fdf2417f4
|
fix(swap): 修复日终持仓风险_互换 利息金额方向处理逻辑
|
2026-08-10 17:59:30 +08:00 |
|
张名锐
|
54445c1e38
|
Merge remote-tracking branch 'origin/glms/feature/zmr-0808' into glms/feature/1.4.2
# Conflicts:
# YLErpDAL/Modules/SwapModule/SwapDealService.cs
# YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs
|
2026-08-10 10:56:34 +08:00 |
|
张名锐
|
2ee38384ac
|
fix(swap): 修复预付金腿计息基数计算问题
- 在多个单元测试文件中添加InterestIncomeSum字段以保持数据一致性
- 修改GLMS20260105PartialCloseDividendBugTest测试,改进EOD快照验证逻辑
- 修复SwapDealService中预付金腿的orginPv计算逻辑,使用上一日保证金本金作为基准
- 更新SwapPositionComposeScenarioTest中的测试数据结构和利率设置
- 修正平仓日利息计算精度问题,使用Math.Round确保计算准确性
|
2026-08-09 22:28:40 +08:00 |
|
张名锐
|
2c4cd56111
|
feat(swap): 添加收益互换利息计算功能及Excel场景测试
- 新增ExecuteSaveEodInterestPositionCopy方法用于保存日终利息持仓副本
- 添加ExcelScenario4Case类和相关测试数据用于验证利息计算准确性
- 实现DI_EXCEL_SCENARIO4_PartialCloseAndFinalCloseMatchBlAndBn测试方法
- 优化SwapDealService中的利息计算逻辑和平仓处理
- 添加详细的注释说明利息计算的核心业务规则
- 完善SwapEodPositionService中的日终持仓处理逻辑
- 修复部分平仓和最终平仓时的利息金额计算问题
|
2026-08-09 22:07:19 +08:00 |
|
张名锐
|
48e8447925
|
fix(swap): 修复复利重置日部分平仓后本金计算逻辑
- 修复复利重置日部分平仓后当日利息计算,使用已结转待实现利息的剩余复利本金
- 修复算尾部分平仓后EOD保留剩余复利本金的逻辑,按计息模式返回口径处理
- 修复模式2和模式9在部分平仓时的本金计算差异,避免重复比例调整
- 修复不算尾情况下重置日后已并入本金的待实现利息遗漏问题
- 新增对话案例回归测试验证部分平仓后最终全平场景的正确性
- 添加多种计息模式和交易类型的回归测试用例
|
2026-08-09 16:06:09 +08:00 |
|
张名锐
|
7528670e8b
|
fix(swap): 修复部分平仓后算尾利息计算问题(算头算尾T+0合约单利)
- 将测试方法改为数据驱动测试以覆盖不同利息模式
- 在测试中添加对不同利息模式的验证逻辑
- 修复平仓后EOD本金只携带剩余持仓的计算逻辑
- 添加对算尾部分平仓后EOD本金的断言验证
- 优化单利算尾当日按平仓前全额计提的处理逻辑
|
2026-08-09 13:42:59 +08:00 |
|
张名锐
|
691054c57e
|
fix(swap): 修复部分平仓后跨日复利本金计算逻辑(算头算尾T+1复利合约)
- 修复了5/11 EOD跨日复利本金应保留剩余70%动态本金的计算
- 调整了calcLast=true时已平部分动态本金的处理逻辑
- 修正了部分平仓后剩余仓位跨日携带的本金缩放算法
- 添加了针对不同计算路径的本金比例调整机制
|
2026-08-08 18:09:31 +08:00 |
|
张名锐
|
d3afa6d27c
|
fix(swap): 修复部分平仓后复利本金计算逻辑(修复T+1)
- 修复部分平仓后下一日复利本金未按剩余比例继承的问题
- 添加对最终日不算尾时历史差分重放的日期边界控制
- 修复算头不算尾快速路径中已平部分进入下一日复利的错误
- 确保重置日动态本金不会被二次缩放导致剩余本金计算错误
- 添加单元测试验证部分平仓后复利本金按剩余70%本金计提的逻辑
- 补充最终全平重放时历史终点包含当日利息后再做差额的测试用例
|
2026-08-08 17:10:29 +08:00 |
|
张名锐
|
aa5a5ed879
|
fix(swap): 修复复利计算中部分平仓场景下的利息处理逻辑(算头不算尾期初复利)
- 修改单元测试为数据驱动测试,支持多种利息模式验证
- 更新复利计算注释,明确最终日重放时的calcLast规则
- 扩展复利计算条件判断,支持合约名义本金规模和标的期初全价两种模式
- 优化部分平仓日终复利计算逻辑,确保未平仓本金贡献正确保留
|
2026-08-08 16:32:50 +08:00 |
|
hjhan
|
46cf7025a4
|
refactor(trace): 计息全路径埋点 + 关键日志常驻落盘
覆盖补全 CalcDailyCompoundInterest / CalcDailySimpleInterestByEod /
CalcDailyCompoundInterestByEod / InitSwapDealInterest 分支与复利跨期直取 /
orginPv 重映射 / preEod.id==0 播种 / ToRemainingClosePercent 语义翻转。
关键决策点改用 Critical() 无条件落盘(IYcLogger.Info, 类别 SwapCalc),
与开关解耦——出问题事后翻日志即可定位,不必事前开开关。
开关态(Header/Line/Day)仅作排障便利(?swaptrace=1 / 单测 Dump)。
纯增日志不改控制流;YLErpDAL 与 UnitTestProject 编译0错,
PrepaidPrincipal trace 测试 2/2 通过(SKIP_INITIALIZATION)。
|
2026-08-08 16:32:16 +08:00 |
|
张名锐
|
54a86fccc1
|
fix(swap): 修复部分平仓后复利计算问题(算头不算尾合约复利)
- 当calcLast为false时,部分平仓日终新增复利使用剩余本金计算
- 修复最终全平仓时历史终点利息计算逻辑
- 添加测试用例验证部分平仓后复利计算准确性
- 修正日终待实现利息累加时的历史终点处理方式
- 调整复利部分平仓金额计算方式,确保未平仓部分正确参与后续计算
|
2026-08-08 16:11:53 +08:00 |
|
hjhan
|
97029897c4
|
feat(swap): SwapCalcTrace 支持运行时按请求开关 + 响应头可见(无需重启)
- SwapCalcTrace 改为双模式:保留全局静态开关(单元测试用 IsEnabled/Dump),
新增请求级 AsyncLocal 缓冲(EnableForRequest/DumpForRequest/ClearForRequest),
由中间件按请求开关,不跨请求串扰。
- 新增 SwapCalcTraceMiddleware:开启方式三选一——URL ?swaptrace=1 /
请求头 X-SwapCalc-Trace:1 / 标记文件 App_Data/swapcalctrace.on(无需重启);
Response.OnStarting 时把逐日计息过程写入响应头 X-SwapCalc-Trace(超长落
logs/swapcalctrace-YYYYMMDD.log 并在头给路径),同时写服务器日志。
开发者在浏览器“网络”面板即可查看,零前端改码、零行为影响、性能可忽略。
- Program.cs 在 ExceptionMiddleware 后注册该中间件。
- 删除 CalcDailyCompoundInterestByEod 遗留垃圾日志 LogFactory.GetLogger("test").Error("lksafhasdhfjas")。
- CalcDailySimpleInterest 两处追踪守卫改为 IsEnabled||IsRequestEnabled。
- 既有 PrepaidPrincipalCloseTraceTest / ClosingChainTraceTest 2/2 仍全绿。
回答用户两点:① dynomicPrincipal 公式字段含义;② 原 Trace 需重启才能开,
现改为前端 otcdebug 式(?swaptrace=1) 即可在响应头看到逐步计息过程。
|
2026-08-08 15:57:00 +08:00 |
|
张名锐
|
6fdc7d80b2
|
fix(swap): 修复复利计算和部分平仓处理中的多个问题(算头算尾合约复利平仓)
- 修复合约名义本金规模模式下部分平仓时名义本金计算错误
- 修复最终全平时复利利息计算中历史平仓尾差处理问题
- 修复复利重置日处理中利息重复注入历史本金的错误
- 修复部分平仓后日终待实现利息计算中本金比例应用问题
- 修复全平且实际金额覆盖应结利息后待实现利息清零逻辑
- 新增复合复利交换服务用于单元测试验证
- 添加多个测试用例覆盖复利计算边界场景
|
2026-08-08 15:51:29 +08:00 |
|
hjhan
|
cd8c3b6c95
|
test(swap): 预付金腿两段式平仓计息过程暴露 + SwapCalcTrace追踪器
- 新增 SwapCalcTrace(零成本可开关追踪器,默认关闭,对生产零行为影响):
在 CalcDailySimpleInterest 埋点,逐日记录计息起点/日终归档 ValueDate 地板/
计息基数 dynomicPrincipal/当日利率/当日利息/累计,便于定位计息异常根因。
- 新增 PrepaidPrincipalCloseTraceTest:用截图参数(本金100000.23/利率2.1111%/
8.4平40%→8.7全平)暴露计息过程,证明第二次平仓利息完全由日终归档 ValueDate
决定——正确归档(ValueDate=8.4)+算尾=3天=10.41(Excel本次利息);
错误归档(ValueDate=8.1)复现系统截图 6天=20.83。守卫1钉正确值10.41,
守卫2复现20.83并证明 ValueDate 即『缺的要素』。
- 修正覆盖结论:浮动端/利息腿已有两段式覆盖,预付金腿两段式此前缺失(缺口
与截图坏『预付金端』一行精确对应)。
|
2026-08-08 15:02:54 +08:00 |
|
hjhan
|
096d2609eb
|
test(swap): 为债券TRS期间结算自动互换10场景补单测 + SaveAutoSwapDeal接缝可测化
- 新增 BondTrsAutoSwapScenarioTest:覆盖测试场景/测试场景-0702复测两页
10个自动互换场景(含付息日历登记日2/28→支付日3/2、资金发生日3/3/3/4)、
部分平仓后按登记日持仓数量计算(剩余60%为54240)、同日多腿合并、
分红支付日偏移、无结算观察日不得凭空产生互换等,共11条断言全绿。
- SaveAutoSwapDeal 改为走 AddClientCash/AddSwapEvent/PersistFlowEvent 接缝
(默认实现与重构前行为一致,零行为变更);UpdateInitalPostion 由 private
改 protected virtual;GetPreDealDate 改 virtual,便于无DB单测。
|
2026-08-08 13:32:22 +08:00 |
|
hjhan
|
d1badfe48f
|
fix(swap): 固定值利息腿平仓比例缩放缺陷(GLMS) + 证明测试
- SwapDealService.CalcNotionalByMode 固定值分支原实现把 closePrincipal 钉成 Fix 全量
且 newClosePercent 强制置 1,导致界面『全部平仓→部分平仓』改比例时利息腿数据
完全不变。修复为 closePrincipal = InterestPrincipalFix * closePercent(与预付金/
多头/空头/标的期初全价等模式一致),posiPrincipal 仍保留 Fix 全量,newClosePercent
保留真实平仓比例,两个缩放入口作用于不同项不双重缩放。
- EOD 结算路径 SwapEodPositionService 传 closePrecent=1 字面量,Fix*1=Fix,日终行为不变。
- 新增 SwapFixedInterestLegClosePercentBugTest(9 例真实函数复现+证明)。
- 纠正 SwapUnwindPrepayPrincipalBugTdd 中把『免疫』当期望的断言为线性缩放。
- 引入溯源:95686f4c(吴方海, EQD-5718, 2026-05-08);newClosePercent=1 祖传自 acbd2e76(2024-06-04)。
|
2026-08-08 10:34:10 +08:00 |
|
hjhan
|
feffc196c6
|
fix(interest): 修复浮动利率部分/全平利息尾差(Bug A/B/C) 并补充回归测试
- Bug A(SwapDealService): 复利早退分支 TdInterestAmount 未乘 closePrecent
- Bug B(SwapDealService): CalcDailyCompoundInterest 用 interest 而非 EOD 四舍五入快照
- Bug C(SwapEodPositionService): 用 oriPosiNotionalValue(平仓前原始本金) 重算平仓利息
- 新增 SwapInterestScenario3And4FloatingTest: 24 个浮动利率用例, 走真实生产函数
(GetInterests / SaveAutoEodWithCloseInterestPosition), 对照 Excel 手算 oracle(AO/BL/BN),
断言容差 0.01, 非 re-baseline; 含 DebugCompare 调试输出便于与生产/Excel 逐项对比
- 附 缺陷分析-利息部分平仓尾差20260807.md 与 oracle 源 xlsx
|
2026-08-08 09:02:05 +08:00 |
|
张名锐
|
c379e31b4d
|
test:日志
|
2026-08-07 23:20:23 +08:00 |
|
张名锐
|
253a89b799
|
test(swap): 添加消费利息场景测试用例并修复重置日利息计算逻辑
- 添加CI_010_EodResetWithoutCloseCarriesFullPendingInterest测试方法
- 验证无平仓重置日必须完整并入上一期累计待实现利息的场景
- 修复CalcDailyCompoundInterestByEod方法中剩余百分比计算逻辑
- 使用posiPrincipal替代preEodPosition.TdInterestPrincipal进行计算
- 确保重置日期计算中本金比例的准确性
|
2026-08-07 23:00:28 +08:00 |
|
张名锐
|
e819ad02c5
|
fix(swap): 修复复利计算中的利息处理逻辑
- 添加了从开始日期到结束日期的天数计算
- 添加了从前一日末到结束日期的天数计算
- 修复了特定条件下利息本金和浮动利率的赋值
- 修正了利息金额和累计利息金额的计算
- 添加了四舍五入处理以确保精度准确性
- 修复了利息平仓损益的计算逻辑
|
2026-08-07 22:13:58 +08:00 |
|
张名锐
|
569002e551
|
fix(swap): 修复重置日期利息计算逻辑
- 修正了 calcLast=false 时重置日取价被跳过的问题
- 确保重置日之前的复利能够正确并入本金
- 调整了计息日判断逻辑的位置以保证本金重置正常执行
- 修复了重置日当天利息不应被计入的逻辑错误
|
2026-08-07 21:54:04 +08:00 |
|
张名锐
|
19d8b2a926
|
Merge remote-tracking branch 'origin/glms/feature/1.4.2' into glms/feature/1.4.2
|
2026-08-07 20:52:13 +08:00 |
|
张名锐
|
5539bd9c9a
|
```
fix(swap): 修复复利模式下部分平仓后EOD本金计算问题
- 在复利模式部分平仓场景中确保使用计算得出的复利本金
- 添加了针对复利重置日期部分平仓的单元测试验证
- 修复了EOD本金重置逻辑,避免复利计算被错误覆盖
- 确保CloseInterestPosition执行后保留正确的复利本金值
```
|
2026-08-07 20:51:56 +08:00 |
|
hjhan
|
66a97e03ef
|
fix(swap): 复利重置日=平仓日时 calcLast 不再跳过 FR007 取价
根因(GLMS-JIATT-20260805):InterestCalcMode='10'(算头不算尾,calcLast=false)时,
CalcDailyCompoundInterest 循环的 'if(!calcLast && accrueDate==endDate) continue'
会跳过平仓日。若平仓日恰好是重置日(i%period==0),取价代码块被一并跳过,
导致 flowEvent.FloatRate 落库为旧周期利率,传染后续 EOD 复利计算。
修复:把重置日的 FR007 取价提前到 calcFirst/calcLast 跳过判断之前——
calcLast 只应跳过'计息',不应跳过'重置日利率取价'。同时循环外用最终
floatRate 兜底赋值 flowEvent.FloatRate,确保落库值反映最后重置日的利率。
验证:
- CI_007 合成测试(平仓日=重置日):修复前 FloatRate=旧值(FAIL),修复后=新值(PASS)
- 连库验证(GLMS-JIATT-20260805 8/4平仓):FloatRate 0.0123→0.0213(8/3新值)
- 利息金额不变(calcLast 不计当天利息,Amount 不受影响,只修正 FloatRate 字段)
- 全套 swap 测试无新增回归(334通过,2失败均为pre-existing单利/EOD路径)
附:CI_007 复现测试 + GLMS20260805 FR007/EOD 诊断工具 + 文档 longRatio 状态更新
|
2026-08-07 20:43:16 +08:00 |
|
张名锐
|
fb5a5d0ab4
|
fix(swap): 修复FR007数据添加时的标的验证和关联逻辑
- 添加对FR007标的存在的验证检查
- 移除冗余的新增数据查询逻辑
- 直接使用查找到的标的ID进行关联
- 集成EodPriceService中的标的ID解析逻辑
- 统一数据源设置为人工来源
|
2026-08-07 19:44:01 +08:00 |
|
张名锐
|
a0be0eb003
|
fix(swap): 修复复利平仓时已结利息扣除计算问题
- 修改 CalcCompoundUnwind 方法添加 closePercent 参数用于部分平仓场景
- 更新复利平仓逻辑,将已结利息按平仓比例进行缩放扣除
- 添加部分平仓测试用例验证已结利息按比例扣除的正确性
- 修复了全部已结利息在部分平仓时被全额扣除的问题
|
2026-08-07 18:36:32 +08:00 |
|