Commit Graph
110 Commits
Author SHA1 Message Date
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
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
张名锐 a0be0eb003 fix(swap): 修复复利平仓时已结利息扣除计算问题
- 修改 CalcCompoundUnwind 方法添加 closePercent 参数用于部分平仓场景
- 更新复利平仓逻辑,将已结利息按平仓比例进行缩放扣除
- 添加部分平仓测试用例验证已结利息按比例扣除的正确性
- 修复了全部已结利息在部分平仓时被全额扣除的问题
2026-08-07 18:36:32 +08:00
张名锐 3a435ad89b fix(swap): 修复平仓事件中事件日期=平仓日期的处理逻辑
- 将平仓条件判断从 UnwindDate 改为 EventDate
- 移除不再使用的 priorClosePositionIds 变量
- 统一使用 NormalizeEventUnwindDate 替代 NormalizeIncomeUnwindDate
- 在多个平仓方法中添加 NormalizeEventUnwindDate 调用
- 更新流程事件的 EventDate 和 UnwindDate 字段
- 修改单元测试以验证按 EventDate 分桶的逻辑
- 在前端控制器中将 unwindDate 设置为 valueDate
- 添加 maxdate 属性到平仓日期选择器
- 实现事件日期与平仓日期的双向同步功能
- 更新利息列表获取接口使用统一日期参数
2026-08-07 13:46:24 +08:00
张名锐 54d65246c6 Merge remote-tracking branch 'origin/glms/feature/1.4.2' into glms/feature/1.4.2 2026-08-07 10:52:20 +08:00
张名锐 a1cdb2cd19 fix(swap): 修正平仓事件日期过滤条件
- 将平仓事件的日期过滤从 EventDate 改为 UnwindDate
- 确保正确识别结算日期后的平仓流程
- 修复平仓事件日期比较逻辑的一致性问题
2026-08-07 10:52:02 +08:00
hjhan 1bf517188c fix(swap): 待结算分红收益(DividendPending)改用 EOD 全量口径,修复 e3c473ba 的硬0回归
e3c473ba 把前端 DividendPending 硬编码 0,对 GLMS-20260105-0004(PosiDividendSum 恰好=0)
测试通过、掩盖问题。但对 PosiDividendSum≠0 的部分平仓交易,硬0 会落库
(SwapFlowEventService:588 冲账取负写入 swap_flow_event.DividendPending)并在事件列表
"待结算分红收益"列显示错误的 0——是确定的回归。

口径论证(代码证据,非拍板):DividendPending(待结算存量) ↔ EOD PosiDividendSum(未实现),
字段名、递推公式(SwapEodPositionService:1825 已扣当日实现)、列标签(SwapflowList:561)、
旧前端意图(posiQty×totalInterest 想表达"平仓后剩余")四处同指全量口径。是存量非流量,
不按本次平仓比例分摊。

改动:
- SwapDealService.InitUnwind:GetPreEodDividendSum 返回值取一次,同时喂 DividendIn 与
  DividendPending(避免重复查库);GetPreEodDividendSum 注释补口径论证+历史教训(防后人改回硬0/分摊)
- 前端 unwindSwapTrade.js:删除 DividendPending=0 硬写,保持后端值不动
- 前端 incomeSwapTrade.js:DividendPending 保持 0(互换=全量结清,结清后待结算归0),
  注释说明与平仓页口径差异
- 测试补非0场景:GLMS-20260706-0004(PosiDividendSum=-150,000)验证返回非0真实值,
  直接针对"硬0被0掩盖"盲区,防止该回归复现

全量构建 0 错误,4 个分红测试全绿(含 0 场景、互换页、无EOD防御、非0场景)。
2026-08-07 09:28:18 +08:00
张名锐 01d7f0c55e fix(swap): 修复部分平仓计息计算中的尾差处理问题
- 修正了部分平仓后待实现利息收入的预期值从 0.006383561644 到 -0.010438356164
- 修正了预期待实现利息值从 0.820569301369 到 0.410474008219
- 在 SwapDealService 中添加了已完成平仓事件的查询逻辑,排除已平仓头寸的本金计算
- 重构了 SwapEodPositionService 中的待结算利息计算逻辑,区分自动互换和平仓场景
- 在测试类中添加了已完成流程事件的查找方法和相关测试数据
- 更新了测试用例以验证平仓事件对利息计算的影响
2026-08-06 21:35:13 +08:00
hjhan e3c473bafd fix(swap): 分红前部分平仓过的交易,后续平仓/互换分红收益改由 EOD 单一可信源提供
问题:GLMS-20260105-0004 在 2/28 部分平仓 40%、3/2 登记日互换后,3/3 继续平仓/互换时
"浮动端平仓盈亏·分红"误显 -36,160(应为 0)。根因:前端 getDivindIn 用期初全额持仓
×totalInterest 重算分红(-90,400),扣除 consumedDividend(-54,240) 后余 -36,160,
恰为已平仓 40%(登记日前已不持有、不享有该笔分红)部分被重复计入。

方案C:分红收益改由后端读上一收盘日 eod_swap_position.PosiDividendSum 提供(单一可信源),
前端不再自算。EOD 的 PosiDividendSum 已按"实际持仓递推 + 当日实现扣除"准确算出待实现分红,
3/2 互换后为 0。因手动平仓/互换后端不重算 DividendIn、直接落库前端值,后端 Init 阶段给出
正确值可同时修正展示与落库。

改动:
- SwapDealService 新增 GetPreEodDividendSum(复用 GetUnwindInterests:624 的上一 EOD 日期推导
  + SwapEodPositionService.GetPreEodPositions),protected virtual 便于测试覆写、无 EOD 返回 0
- InitUnwind/InitIncome 的 floatEvent.DividendIn 从硬编码 0 改为 GetPreEodDividendSum 返回值
- unwindSwapTrade.js/incomeSwapTrade.js getDivindIn 删除 GetBondPayMentInterest 调用与全部自算,
  保留后端 DividendIn 值、DividendPending=0
- GetBondPayMentInterest 加废弃文档注释(保留接口供历史调用,consumedDividend 无日期过滤隐患随废弃消解)

测试:GLMS20260105PartialCloseDividendBugTest 连真实库验收——3/3 平仓/互换 DividendIn=0(修复前
-36,160)、无 EOD 防御返回 0。全量构建 0 错误。
2026-08-06 19:09:45 +08:00
马冰冰 9f6224f44e Merge branch 'glms/feature/1.4.2-0806' into glms/feature/1.4.2 2026-08-06 14:45:37 +08:00
马冰冰 15bf1a90ab fix:手动互换不再产生应付预付金支出 2026-08-06 14:44:30 +08:00
张名锐 9ef45650c7 feat(swap): 实现预付金利息腿实时剩余本金计算功能
- 新增 ResolveInterestLegPositionsAsOf 方法处理预付金利息腿实时本金计算
- 添加 FindCompletedFlowEvents 方法查询已完成的现金流事件
- 在日终持仓服务中集成实时剩余本金计算逻辑
- 移除日终重复扣减预付金本金的逻辑
- 优化利息端估值计算方式
- 添加部分平仓后预付金日终按实时剩余本金计息的测试用例
- 增加平仓日预付金日终不得重复扣减实时剩余本金的验证
- 完善历史回放场景下的本金调整功能
2026-08-06 14:32:38 +08:00
张名锐 6bbe9b1c13 fix(swap): 解决互换交易全额平仓计算和判定问题
- 在前端计算函数中添加全额平仓时返回剩余数量的逻辑
- 添加针对 trade2308 问题的单元测试验证全额平仓场景
- 实现后端全额平仓请求标准化处理方法 NormalizeFullCloseRequest
- 添加重新计算标准化平仓金额的方法 RecalculateNormalizedUnwindAmounts
- 实现平仓后是否全额关闭的判定逻辑 IsFullCloseAfterDeduction
- 在平仓流程中集成全额平仓标准化处理和金额重新计算
- 更新平仓后交易状态和剩余金额数量的处理逻辑
- 完善审批流程中的平仓数据标准化和流动事件处理
- 优化持仓扣减时全额平仓的处理逻辑
- 添加多个单元测试验证各种全额平仓场景的正确性
2026-08-06 13:24:41 +08:00
tengyufan 46316c1400 fix: 恢复互换平仓交易费用按基础费率计算 2026-08-05 18:26:15 +08:00
张名锐 613fd66b65 fix(swap): 解决(观察日)利率计算精度问题并优化价格精度处理
- 在SwapDealService中对GetFixedRate结果进行精度调整,解决原数据精度误差问题
- 在swapPricePrecisionHelper中添加roundDecimal方法并移除TODO注释
- 新增observationRate相关的精度处理函数,包括roundObservationRate和percent转换函数
- 创建serializeSwapIntervals函数用于处理掉期区间利率精度序列化
- 将consNumberFormat.umpriceP替换为swapPricePrecision.shiftDecimal进行百分比转换
- 使用新的精度处理函数替代原有的toFixed(6)和乘以0.01的操作
2026-08-03 13:21:23 +08:00
张名锐 3670dde9bf fix(swap): 修复利息互换平仓结算中的尾差处理和本金计算问题
- 修复ExecuteSaveAutoEodInterestPosition方法参数传递,添加lastEodSwap、posiLongNotional和orginPv参数
- 修正平仓利息计算逻辑,区分手动结算和平仓后自动结算的利息处理
- 新增ResolveUnwindPreviousNotional静态方法,优化平仓前本金计算逻辑
- 修复部分平仓后利息累积边界问题,确保仅从上次EOD快照后开始计算
- 完善自动结算利息的四舍五入处理,避免精度丢失
- 修正支付端方向符号应用,确保方向只应用一次
- 更新TdInterestPrincipal计算逻辑,处理不同利息模式下的本金赋值
- 修复TdCloseInterest计算,合并手动和自动结算利息金额
- 优化InterestIncomeSum计算,正确处理结算后剩余未实现利息
2026-07-30 23:29:07 +08:00
张名锐 85f1bccb24 Merge branch 'glms/feature/1.4.2' into glms/feature/dotnumber
# Conflicts:
#	YLErpWeb/App_Data/Config/otcformat.js
#	YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml
#	YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js
2026-07-30 10:50:44 +08:00
张名锐 3d73835be5 fix(swap): 结算或全部平仓后,待实现置0
- 添加 NormalizeSettledInterestAmounts 方法处理手工平仓和互换的利息事件精度
- 添加 NormalizeManualSettlementAmounts 方法在手工结算前收敛流水金额
- 将利息计算精度从 ConsGlobal.PriceRound 统一调整为 InterestCalculationPrecision(12位)
- 在日终持仓快照中添加精度标准化处理,利息腿保留12位精度
- 修复全量平仓时待实现利息和费用的清零逻辑
- 在收益结算事件后清空待实现利息余额避免重复计算
- 更新单元测试验证现金与两位利息事件的一致性
2026-07-29 14:42:03 +08:00
tengyufan 8c4f452482 fix: 统一互换部分平仓交易费用与待结算费用的分摊舍入 2026-07-29 13:47:45 +08:00
tengyufan e1d68393f8 fix: 修复基础费率平仓待结算费用按实际平仓规模分摊 2026-07-29 13:07:55 +08:00
张名锐 fd2a054764 feat(swap): 实现互换交易价格精度控制功能 init
- 添加 swapPricePrecisionHelper.js 工具类处理价格精度格式化
- 新增 swappriceprecision.js 配置文件定义各类金融产品的精度规则
- 在 EodPositionRisks.cshtml 和 SwapIncome.cshtml 中引入新的价格格式化脚本
- 替换原有的价格格式化函数为基于产品类型的动态精度控制
- 移除旧的价格验证和标准化逻辑,改用新的精度控制机制
- 添加 vue-swap-price-input 组件用于精确的价格输入控制
- 更新 Controller 中的价格处理逻辑以支持新精度格式化方式
2026-07-29 09:44:04 +08:00
tengyufan 4987962aca #EQD-6597 国联民生-簿记时新增基本费率字段(开平仓费用),并且自动计算
feat: 完善互换平仓交易费用自动计算

- 支持百分比和单位数量模式自动计算平仓交易费用
- 支持全部平仓和部分平仓联动重算
- 保持手动互换不自动填充平仓交易费用
- 补充前后端相关单测
2026-07-27 11:57:20 +08:00
tengyufan a575de7bbe Revert "feat(swap): 新增基础费率字段,支持百分比/单位数量模式切换及自动计算"
This reverts commit c9071a4eff.
2026-07-27 09:45:41 +08:00
tengyufan c9071a4eff feat(swap): 新增基础费率字段,支持百分比/单位数量模式切换及自动计算
- 浮动收益端新增基础费率列(原单位交易费用),位于数量与交易费用后付之间
- 支持百分比模式(4位小数)与单位数量模式(2位小数)切换,默认百分比
- 填入基础费率后自动计算交易费用后付,手动修改后反算基础费率
- 平仓时根据 PosiFeeType 自动计算平仓交易费用,支持全部/部分平仓联动
- 收益结算(手动互换)不自动填充平仓交易费用
- 查看交易页面新增基础费率展示(百分比带%后缀4位,单位数量2位)
- swap_position 表新增 PosiFeeType 字段标识费率模式(0=百分比 1=单位数量)
- 切换模式时基础费率和交易费用归零,避免精度冲突
- 修复 TradeView.cshtml 引用了不存在字段 category_tag 的编译错误
2026-07-24 17:32:07 +08:00
张名锐 bc961c3411 fix(swap): 修复互换交易中债券价格精度处理问题,扩充到11位计算
- 统一债券价格四舍五入规则,使用AwayFromZero模式
- 为债券类型添加特殊的精度处理逻辑
- 修复前端价格显示精度计算问题
- 优化价格存储精度控制,区分债券和其他产品类型
- 修复初始化YTM和净价精度处理问题
- 更新价格验证逻辑以支持动态精度设置
2026-07-23 11:06:50 +08:00
张名锐 c58a9d40c4 feat(swap): 统一【期初、期末交割价格】精度处理
- 在ConsGlobal中新增SwapDeliveryPriceRound常量定义为9位小数
- 更新incomeSwapTrade.js中交割价格计算逻辑,添加getStorageDeliveryPrice方法
- 修改SwapConsumerService中TradingAmountAvg字段的精度处理
- 添加ValidateDeliveryPrices和NormalizeDeliveryPrices方法进行交割价格验证和标准化
- 在SwapEodPositionService中对PosiGrossPrice和UnderlyingPrice进行精度处理
- 更新SwapFlowEventService中TradingAmountAvg字段的精度处理
- 在SwapFlowImportService中添加交割价格精度处理
- 更新前端界面中的输入格式配置,使用新的交割价格精度设置
- 修改SwapflowList.js中交割价格精度处理逻辑
- 在SwapFlowService中添加交割价格验证和精度处理
- 更新SwapTradeAutoService中交割价格精度处理
- 修改SwapTradeService中PosiGrossPrice字段的精度处理
- 更新unwindSwapTrade.js中交割价格计算逻辑
2026-07-22 14:53:46 +08:00
张名锐 0755233ab6 fix(swap): 统一处理【名义本金】数值精度舍入问题
- 在多个位置添加 Math.Round 函数确保金额计算精度
- 新增 NormalizeNotionalValues 方法统一处理 UnwindData 中的名义本金舍入
- 修复交易平仓时 StockEqvNotional 扣减计算的精度问题
- 解决持仓数据 PosiNotionalValue 的精度舍入处理
- 修复前端页面显示格式化问题
- 添加单元测试验证名义本金舍入逻辑正确性
2026-07-22 13:05:49 +08:00
hjhan a179675efd refactor(swap-deal): 前端盈亏校验抽为 SwapFrontendPnlValidator
BuildFrontendValidationDiffs/FrontendPnlDiff/AddDiffIfOverThreshold 从2043行 SwapDealService 移至新文件,本文件仅留调用+日志。纯位置迁移,零行为变更。
2026-07-21 15:28:14 +08:00
hjhan e261137c1d fix(swap): 修复多次部分平仓 ClosePercent 口径(A占期初→B占剩余)转换缺失
- SwapDealService.ApplySwapTrade 入口补 ToRemainingClosePercent(A→B) 转换,与 SwapUnwind 保持一致;缺此转换导致 SaveSwapDealInternal 的 B→A 还原出错(GLMS-20260701-0006:第二次部分平仓50%被错误还原为32.5%)
- unwindSwapTrade.js 改用 swapCalc.calcCloseQtyByOriginalPercent 的 roundHalfAwayFromZero,规避 JS 浮点精度偏差(32500000*(0.5/0.65) 应为 25000000)
- SwapUnwind.cshtml 引入 swapCalc.js
- 新增 ApplySwapTradeClosePercentBugTest 回归测试;补充 swapCalc.test.js 精度用例与 GLMS20260701DbDiagnoseTest 诊断测试([Ignore])
2026-07-17 10:59:18 +08:00
张名锐 415539704d fix(swap): 修复债券结息价差盈亏计算逻辑
- 将价差盈亏计算从使用CloseNotionalValue改为使用PositionQty和ContractSize
- 更新前端JavaScript代码中的计算公式,按持仓数量和合约乘数计算价差盈亏
- 在UnwindInput模型中添加PositionQty和ContractSize字段
- 修正后台计算服务中的数据映射逻辑
- 添加FC_009测试用例验证债券价差按数量计算的正确性
- 更新现有测试用例的输入参数以匹配新的计算方式
2026-07-17 10:58:31 +08:00
hjhan 43679393bb test(swap): 补 e2fb456b InitUnwind 默认 ClosePercent 单元测试
抽 CalcDefaultInitClosePercent 静态纯函数(PosiNotionalValue/NotionalValue), InitUnwind L270 改为调用此函数, 新增 6 个单元测试覆盖: 未平仓/已平30%/除零保护/GLMS-20260701-0013 真实快照/与 ToRemainingClosePercent 联动自洽不变式/全平完边界场景. 填补 e2fb456b 提交的测试覆盖缺口.
2026-07-17 08:23:50 +08:00
hjhan e2fb456bc3 fix 平仓(InitUnwind L267)硬编码 1而不是剩余平仓比例 2026-07-16 20:07:50 +08:00
hjhan 238824f4f4 fix(预付金返回/平仓比例): 恢复占期初语义并在后端入口统一转占剩余
之前提交 4f46e263 误将平仓比例改为占剩余持仓(Definition B)语义,与需求不符。
正确需求:每次打开平仓/提前终止均基于最开始原始名义本金(Definition A),
但每次返回的预付金金额需正确(后端按占剩余计算)。

- SwapDealService: 新增 ToRemainingClosePercent/ToOriginalClosePercent 双语义转换;
  SwapUnwind 入口把前端传来的占期初(A)转为占剩余(B),全计算链公式不动;
  SaveSwapDealInternal 序列化前还原为 A 落库,事件列表读取即显示占期初比例。
- SwapTrade2Controller.GetUnwindInterestList: 接收期初/剩余名义本金,预览利息按 B 计算。
- unwindSwapTrade.js: 回退为占期初语义(ClosePercent/平仓名义本金用 NotionalValue,
  oriClosePercent=剩余/期初),提前终止同理。
- 单测 UW_007/008 覆盖 A→B 全平/部分平仓判定。

不影响收盘后盯市/估值(仅平仓入口与展示口径)。
2026-07-16 19:54:26 +08:00
hjhan 24266cfad4 fix(swap): 多次部分平仓预付金返还默认显示初始值(GLMS-20260701-0008)
根因: GetUnwindInterests 利息腿迭代源取 origPositions(IsInitial=1),
其预付金腿 InterestPrincipalFix 恒为初始值(99000); 而"当前剩余本金"(73260)
存于实时腿 realPositions(IsInitial=0)。CalcNotionalByMode 与 InitSwapDealInterest
均读 position.InterestPrincipalFix, 导致多次部分平仓后平仓页默认按初始本金计算
返还。首次平仓 orig==real 掩盖了 bug, 故此前"只修好一次部分平仓"。

修复: 抽纯函数 ResolveInterestLegPositions(orig, real)——迭代源仍用 origPositions
(保留 orig.id -> eod_swap_position.PositionId 的日终匹配, 全库 eod 均按 orig.id 归档,
换 realPositions 会破坏 preEod 匹配导致利息重算错误), 仅对预付金腿(初始5/追加6)
Clone 覆盖 InterestPrincipalFix 为实时腿剩余本金; real.PositionId == orig.id 精确
1:1 关联; orig==real 时返回原始腿本身不克隆。

测试: 新增 SwapUnwindPrepayOrigVsRealBugTdd(6 用例)直接单测该纯函数, 覆盖既有
19 个用例(均绕过 orig/real 选择)的盲区。dotnet test --filter SwapUnwindPrepay
25 passed(19+6) 失败 0。
2026-07-16 10:49:12 +08:00
锦麟 王 592ad52ecb 互换平仓审批流程逻辑 2026-07-15 10:51:58 +08:00
hjhan adc22a5b4c refactor(swap): 合并 CalcDailySimpleInterest 重置日/非重置日重复分支
两分支除"重置日重取浮动利率"外本金口径完全一致(都只缩放一次),
原非重置日分支是复制重置日逻辑时多写一行 tdDynomicPrincipal = flowEvent.InterestPrincipal
(已含 closePercent) 导致 closePercent^N 的指数 bug。合并为单分支,仅在
i % interestPeriod == 0 时重取利率,本金处理统一为 InterestPrincipal = 基数×closePercent。

行为保持:SwapModule 全量 196 通过/4 跳过,与重构前一致。
2026-07-14 17:23:33 +08:00
hjhan 83a55dab33 fix(swap): 修复平仓预付金应返还本金被 closePercent^N 指数级缩小
根因:CalcDailySimpleInterest 单利非重置日 else 分支曾把已×closePercent 的
InterestPrincipal 回填给计息基数 tdDynomicPrincipal,使下一个非重置日再乘一次,
累积成 InterestPrincipal = Fix × closePercent^N(N=计息天数),部分平仓时指数级缩小。
100% 因 1^N=1 不显现,故此前漏测。

修复:非重置日与重置日、日终 CalcDailySimpleInterestByEod 三者对齐——
显示本金 InterestPrincipal = 基数×closePercent(只缩放一次),计息基数不缩放。

TDD 铁证(GLMS-20260701-0006, interest_rest_days=7, Fix=9,180,000):
- 修复前 50%→71,718.75(=Fix×0.5^7)、10%→0.918(=Fix×0.1^7)
- 修复后 50%→4,590,000、10%→918,000、100%→9,180,000
新增 CalcUnwindMultiDay helper + 3 用例,SwapUnwindPrepayPrincipalBugTdd 共 9 绿,
SwapModule 全量 186 通过无回归。
2026-07-14 16:33:59 +08:00
hjhan f7988e8fd3 fix: 修正预付金腿平仓计息基数 orginPv 维度错误导致应返还本金巨负
平仓(盘中)路径对预付金(保证金)腿将 orginPv 取为整笔交易名义本金,
使公式 dynomicPrincipal=TdInterestPrincipal+posiPrincipal-orginPv 把名义本金
(千万~亿级)当减项扣掉,导致"应返还本金"(InterestPrincipal)与计息基数变成巨负值。

修复:仅对初始预付金(5)/追加预付金(6)腿,将 orginPv 对齐为自身保证金本金
InterestPrincipalFix,与日终(EOD)路径 SwapEodPositionService 中预付金腿
orginPv=InterestPrincipalFix 的既有正确行为保持一致。债券本金腿(模式9)及其它
计息模式仍用交易名义本金,不受影响。

新增 SwapUnwindPrepayPrincipalBugTdd 回归测试(6 用例全绿),含客户截图级
0 误差复现、真实库 Trade1813 复现、多次部分平仓及计息基数断言。
2026-07-14 11:33:15 +08:00
张名锐 05d3e9bc52 fix(swap): 修复收入值日期计算逻辑
- 移除非节假日调整逻辑,直接使用行使日期前一天作为最大收入值日期
- 简化日期计算流程,避免节假日调整导致的潜在错误
2026-07-06 16:49:11 +08:00
张名锐 6835a593b0 feat(swaptrade): 添加收益结算日期验证和限制功能
- 新增 MaxIncomeValueDate 属性用于限制收益结算日期上限
- 实现 parseLocalDate 函数用于解析本地日期格式
- 在前端添加日期选择器的最大日期限制和验证逻辑
- 添加 isAfterMaxIncomeValueDate 和 validateIncomeValueDate 方法进行日期验证
- 在后端添加 GetMaxIncomeValueDate 方法计算最大收益结算日期
- 实现 ValidateIncomeValueDate 对收益结算日期进行服务器端验证
- 添加 NormalizeIncomeUnwindDate 方法统一处理平仓日期
- 在模型中新增 MaxIncomeValueDate 非映射属性用于前端显示
- 更新日期格式化函数确保日期字符串的一致性处理
2026-07-06 15:20:21 +08:00
hjhan 32bcf9beb9 refactor(swap): FindTrade seam上提基类消除三子类重复
SwapDealService/SwapEodPositionService/SwapFlowEventService 三处 FindTrade(int)
签名和实现完全一致(DbContext.trade.Find),上提到 SwapTradeBaseService 基类。

核对确认可安全上提的只有 FindTrade(三者逐字一致):
- FindTradeExtend 不可上提: SwapEodPositionService 用 FirstOrDefault,
  SwapFlowEventService 用 First(找不到抛异常),语义不同。
- FindPositions 不可上提: SwapEodPositionService 含 IsInitial 持仓,
  SwapFlowEventService 排除 IsInitial + AsNoTracking,语义不同。

测试 stub override FindTrade 跨基类层级正常工作,C# virtual 多态不受影响。
SwapModule 171测试全绿,无回归。
2026-07-03 09:52:57 +08:00
hjhan e4a92c93ee feat(swap): 后端只读校验告警-搬FrontendCalcReference+SwapIncome/SwapUnwind插校验
前端保持快速反馈(用户改输入立即算),后端不替代前端,仅做合理性兜底校验。

1. 搬FrontendCalcReference到YLErpDAL/Helpers(测试与生产共用同一份公式,避免分叉)
   - 从FrontendCalcCharacterizationTest提取,改public,8个FC测试搬迁后全绿验证一致

2. SwapDealService新增ValidateFrontendPnL只读校验:
   - 从unwindData.FlowEvents取浮动腿,PosiGrossPrice==0时跳过(避免误报)
   - 调FrontendCalcReference重算,与前端传值逐字段比对
   - 差异>0.01记Logger.Error(带输入快照便于排查)
   - 整体try/catch吞异常,校验自身错误绝不阻断交易
   - SwapUnwind/SwapIncome各插一处(FindTrade后、ExecuteInTransaction前)

不碰NLog配置(告警进Console,生产由运维采集)。SwapModule 157测试全绿。
2026-07-03 09:04:57 +08:00
hjhan 129e4bed0d test(swap): 补ApproveSwapTrade/ApplySwapTrade测试+3个seam(借鉴testable分支)
借鉴 origin/glms/feature/refactor-swap-event-testable 的 SwapUnwindScenarioTest 场景4/5,
补全当前分支缺失的平仓审批流程覆盖。

SwapDealService 新增3个 protected virtual seam:
- FindSwapEvent(查待审核事件)
- FindFlowEventsByEventId(查事件关联流水)
- CloseReCheckSetTrade(前置校验包装)
ApproveSwapTrade/ApplySwapTrade 重构为调seam,生产行为不变。

SwapDealSettlementTest 新增2个测试(SD_005/006,共6个):
- SD_005 ApproveSwapTrade 全平仓审核: 反序列化swap_event.EventData→资金流水→TradeStatus
- SD_006 ApplySwapTrade 提交审核: CloseReCheck前置校验+SwapRealizedPnL=SwapCloseAmount

融合策略: 保留当前分支SwapIncome资金流水断言独特价值(SD_001/002),
借鉴testable分支审批流程覆盖(SD_005/006),不二选一。
SwapModule 157测试全绿,无回归。
2026-07-03 08:30:36 +08:00
hjhan a207927f1b test(swap): SwapDealService抽7个virtual seam + 手动结算内存测试
攻克SwapIncome/SwapUnwind零单元测试覆盖的盲区(此前仅DBRecording,CI不跑)。

SwapDealService补7个protected virtual seam(参考已验证的SwapEodPositionService模式):
- FindTrade/AddClientCash/SaveSwapDeal(原private改protected virtual)
- SaveAllChanges/ExecuteInTransaction/CallSaveSwapTradeClientCash/TriggerRealtimeSwapPosition
生产实现行为不变,SwapIncome/SwapUnwind/ApproveSwapTrade重构为调seam。

新增SwapDealSettlementTest.cs(4个内存测试):
- SD_001 SwapIncome资金流水金额=-SwapRealizedPnL
- SD_002 含预付金返息双流水
- SD_003 SwapUnwind全平仓持仓归零+状态变更
- SD_004 DealFloatPosition含费价重算(后端唯二真做计算处)
红灯验证通过(改错金额符号测试立即失败)。
2026-07-03 08:22:43 +08:00
张名锐 b2dce0e4f7 fix(swap): 修复互换交易流程事件数据填充问题
- 添加SwapTradeNo、EventType和EventReason字段到流程事件
- 修正EventType枚举类型从SwapEventTypeEnum改为SwapFlowEventTypeEnum
- 在SaveSwapDeal方法中添加交易信息验证逻辑
- 提取FillSwapFlowEvent方法统一处理流程事件数据填充
- 优化数据库保存操作确保数据一致性
2026-07-02 14:28:47 +08:00
hjhan f501ee95a7 test(swap): 复利consumedInterest扣除合成测试(补c6adb3bb覆盖缺口)
c6adb3bb加的复利consumedInterest扣除此前无任何测试覆盖。
现在用4个合成测试完整验证:

改动(SwapDealService.cs):
- GetConsumedInterest加virtual关键字(测试可override注入内存值)

新增(ConsumedInterestScenarioTest.cs):
- StubSwapDealService override TryGetFloatRate+GetConsumedInterest
  (模仿T0/T1的StubSwapDealService模式)
- CI_001: 基线(consumedInterest=0)拿到全程复利利息
- CI_002: 注入consumedInterest后利息=基线-consumed(直接验证cs:793)
- CI_003: 守恒(consumed+利息=基线)×3组不同consumed值
- CI_004: 全部已结(consumed=基线)平仓≈0不为负(防双重扣减)

关键发现:测试必须传settment:false走盘中平仓路径(CalcUnwindInterest),
settment:true(默认)走收盘归档路径(CalcEodInterest)不传consumedInterest。

验证: 89(T0/T1)+7(DealInterests)+4(ConsumedInterest)=100全通过。
2026-07-01 18:40:48 +08:00