Commit Graph
318 Commits
Author SHA1 Message Date
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
张名锐 6d6729cf9c test(swap): 添加部分平仓利息计算测试用例
- 添加算尾部分平仓当日新计利息包含已平仓部分的测试
- 添加不算尾部分平仓当日新计利息只包含剩余持仓部分的测试
- 验证部分平仓待实现收益计算的正确性
2026-08-07 15:05:04 +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
张名锐 68c3e63c16 Merge remote-tracking branch 'origin/glms/feature/1.4.2' into glms/feature/1.4.2 2026-08-06 18:39:55 +08:00
张名锐 c425594833 feat(swap): 实现预付金模式下部分平仓的待实现收益计算
- 添加DI_MANUAL_PREPAY_PARTIAL_CLOSE_UsesHistoryPlusRemainingDailyInterest测试方法
- 验证预付金部分平仓待实现收益为历史待实现加平仓后当日新增减平仓实现
- 修改ExecuteSaveAutoEodWithCloseInterestPosition方法中待实现收益计算逻辑
- 新增useAccrualBalance标识判断是否使用应计余额计算方式
- 对于预付金模式使用历史待实现收益加当日新增减平仓实现的方式计算
2026-08-06 18:39:20 +08:00
tengyufan 02eb592399 fix: 限制互换展期新到期日不得早于原到期日 2026-08-06 17:45:43 +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