ruisu
|
995cac356b
|
feat:尝试解决与test分支的冲突
|
2026-08-24 15:11:43 +08:00 |
|
ruisu
|
f2a1598d1d
|
feat:增加平仓所需风控上下文要素
|
2026-08-14 15:16:36 +08:00 |
|
ruisu
|
8d58ef15e8
|
feat:在平仓时增加风控校验,创建通用超时教研函数,以备交易确认老风控下线后接入。
|
2026-08-06 16:00:25 +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 |
|
张名锐
|
f37a5b997c
|
Merge remote-tracking branch 'origin/glms/feature/1.4.2' into glms/feature/1.4.2
|
2026-07-17 10:02:18 +08:00 |
|
张名锐
|
ce0908c53b
|
fix(swap): 修复浮动端已实现盈亏计算逻辑
- 添加了SetFloatingRealizedPnl方法统一计算已实现盈亏
- 已实现盈亏现在正确包含盯市、分红和费用三个组成部分
- 修复了多处RealizedPnl计算错误,确保数值准确性
- 为DF_008测试场景添加了专门的单元测试验证
- 移除了重复的盈亏计算代码,提高代码可维护性
|
2026-07-17 10:02:06 +08:00 |
|
hjhan
|
2395aa9856
|
test(swap): 补 6676b625 掉期保证金利息方向反向单元测试
抽 CalculateSwapRealizedPnl 为 public static 纯函数(用 ConsTrade.InterestMarginModels 替代实例 marginTypes), 新增 8 个单元测试覆盖: 非保证金腿收取/支付原向, 保证金腿(初始预付金/追加预付金)收取/支付反向, 完整 5 字段汇总两种方向, RealizedInterest=0 边界. 锁定 6676b625 修复的保证金腿利息方向反向契约, 防止后续误改回归.
|
2026-07-17 08:40:19 +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 |
|
张名锐
|
55e4c5776b
|
Merge remote-tracking branch 'origin/glms/feature/1.4.2' into glms/feature/1.4.2
|
2026-07-16 19:55:57 +08:00 |
|
张名锐
|
6676b62573
|
fix(swap): 修正掉期产品保证金利息计算逻辑
- 修正FloatingUnrealizedPnl字段定义,包含未结交易费用
- 更新MarginInterestGain和MarginInterestLoss字段的文档说明
- 添加CalculateSwapRealizedPnl方法处理保证金腿利息现金流方向
- 修正RealizedPnL计算逻辑,避免保证金利息重复计算
- 调整保证金本金和利息计算口径的一致性处理
- 修正保证金利息现金流方向与本金方向的相反关系
|
2026-07-16 19:55:44 +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 |
|
张名锐
|
4f5af864dc
|
Merge branch 'glms/feature/valuation_0709_zmr' into glms/feature/1.4.2
|
2026-07-14 11:16:45 +08:00 |
|
张名锐
|
076a846cb9
|
fix(swap): 修复互换模块债券日终估值价格转换问题
- 新增 GetSwapValuationPrice 方法处理债券价格格式转换
- 解决新录入页面全价按小数保存与历史数据格式不一致问题
- 当期初价为小数口径且当前债券价为展示态时进行格式转换
- 避免因价格格式差异导致的浮动损益计算错误
- 在三个关键位置替换原有价格获取方法调用
- 添加详细的日志记录用于跟踪价格转换过程
|
2026-07-14 10:55:47 +08:00 |
|
张名锐
|
4449bd5824
|
feat(swap): 更新互换估值功能并优化数据模型
- 添加互换估值V1配置常量以支持新版本
- 将PeriodAmount和DividendAmount字段改为可空decimal类型
- 更新字段注释说明预付金利率和利息的计算方式
- 修改净额结算金额定义,排除期初和追加预付金本金
- 在报表服务中添加安全求和操作防止空值异常
- 增加多个汇总字段包括股息、保证金利息等统计
- 重构预付金处理逻辑,改用加权平均计算方式
- 新增加权保证金利率和利息计算辅助方法
- 调整前端表格列顺序,优化交易编号显示位置
- 更新数值格式化器以支持空值处理和精度控制
- 添加文档列顺序恢复功能确保表格一致性
|
2026-07-14 09:46:54 +08:00 |
|
hjhan
|
18ba0271ec
|
refactor: eod 数据来源写库改用 EodPriceBase 常量
EodSyntheticPriceSaveService 三处 DataSource="系统"、SwapFlowService 一处 DataSource="人工",均改为引用既有 EodPriceBase.系统/人工 常量,消除 eod 数据来源列值散落字面量。仅统一“数据来源”语义,不动无关的系统操作员名(OptName/UserName 等)字面量。
|
2026-07-13 16:56:04 +08:00 |
|
张名锐
|
7df9e8060e
|
feat(swap): 添加互换合约估值功能和优化数据模型
- 在ClientSwapPositionRequest中新增BookId字段用于资产分类查询
- 新增FloatingUnrealizedPnl、InterestPaymentMethod、MaturityNettingValuation等估值相关字段
- 添加MaturitySettlementDate、DividendAmount、AdditionalMarginAmount等持仓详情字段
- 更新前端表格列模型,调整浮动端和估值实现收益分组显示
- 实现框架合约导出功能,支持完整数据筛选结果导出
- 优化名义本金计算逻辑,修复长短仓数值处理问题
- 完善付息方式和估值口径的业务逻辑处理
- 添加TRS估值、期间分红等关键业务字段计算
- 实现Excel导出时分组表头格式化功能
- 修复框架合约列排序和分组表头显示问题
|
2026-07-10 18:20:20 +08:00 |
|
张名锐
|
358993bedb
|
feat(swaptrade): 添加期末头寸风险表新字段支持
- 在EodSwap实体模型中新增标的类型、期间付息/分红、保证金利息收支字段
- 在前端表格列模型中添加标的类型、期间付息/分红列定义
- 在前端表格分组配置中将新字段归入对应分组显示
- 实现后端服务中对新字段的数据查询和计算逻辑
- 添加保证金利息收入支出的分类汇总功能
- 完善标的类型字段的数据源获取和展示逻辑
|
2026-07-09 15:11:58 +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
|
86825cb2a1
|
test(swap): SwapPositionComposeScenarioTest(4场景)+CopyEodPosition/UpdateEodPosition/SaveCurrentEodInitalPosi走PersistEodSwapPosition seam
借鉴 testable 分支 SwapPositionComposeScenarioTest,基于当前分支 seam 重写4场景:
- SPC_001 首次归档(无前日eod):PosiQuantity=初始持仓
- SPC_002 Copy分支(有前日eod无事件):PosiGrossPrice原样复制
- SPC_003 Update分支(有平仓事件):PosiQuantity=1000-400=600, TdCloseQty=400
- SPC_004 未收盘抛异常(非交易首日无前日eod)
SwapEodPositionService 改动(零行为变更):
- CopyEodPosition/UpdateEodPosition/SaveCurrentEodInitalPosi 的 DbContext.eod_swap_position.Add
改为调 PersistEodSwapPosition seam(3处),使测试可拦截持久化
利息腿场景(自动互换)因 CalcSwapInterests 参数适配复杂留后续。
SwapModule 177测试全绿(+4),无回归。
|
2026-07-03 18:37:46 +08:00 |
|
hjhan
|
cbb5c88aa8
|
refactor(swap): SwapPositionCompose补5个seam+事务重构为ExecuteInTransaction
SwapEodPositionService 新增5个 protected virtual seam(SwapPositionCompose路径):
- FindActiveSwapTrades(DateTime, IEnumerable<int>): 查活跃互换交易
- FindAllSwapPositions(List<int>): 查所有持仓(含初始+实际)
- FindTradeExtends(List<int>): 批量查交易扩展
- FindEodSwapsByDate(DateTime): 查指定日期日终汇总
- FindFlowEvents(int, DateTime): 查交易指定日期的完成流水事件
SwapPositionCompose 方法体重构:
- 5处内联DbContext查询替换为seam调用
- 事务(BeginTransaction/Commit/Rollback)重构为ExecuteInTransaction lambda
- SaveChanges替换为SaveAllChanges seam
- 复用已有FindEodSwapPositions seam(替代内联eod_swap_position查询)
为零行为变更(seam生产实现=原代码,ExecuteInTransaction=原事务逻辑)。
SwapModule 173测试全绿,无回归。为SwapPositionComposeScenarioTest铺路。
|
2026-07-03 18:31:01 +08:00 |
|
hjhan
|
9da3a1ed91
|
refactor(swap): ClearSwapPositions改virtual(为重复收盘端到端测试铺路)
SwapTradeBaseService.ClearSwapPositions 从 public void 改为 public virtual,
使测试子类可 override 模拟清理逻辑(按ClientCashId关联删除出入金)。
为零行为变更(未被override时按原实现执行)。SwapModule 171测试全绿,无回归。
为后续 DuplicateSwapIncomeReproductionTest(重复收盘不累积出入金)端到端测试铺路。
当前分支已有 ClearSwapPositionsScenarioTest(CSW_001-004)覆盖清理单元逻辑,
端到端测试将补充'重复收盘场景'的集成验证。
|
2026-07-03 17:53:18 +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
|
b501e21904
|
test(swap): 启用MergeCompose场景6/7+SwapFlowEventService录制钩子+RecordingSwapFlowEventService
1. MergeComposeScenarioTest 场景6/7 启用(去掉Ignore):
此前失败是stale binary(未重新编译),重新build后8场景全部通过。
- 场景6 单条merge无持仓→DealNoPosition创建交易
- 场景7 两条merge无持仓→创建交易+平仓
2. SwapFlowEventService 补OnBefore/OnAfterMergePageEvent录制钩子(默认空实现):
- OnBefore: DB查询完成、合成逻辑执行前触发,可捕获输入快照
- OnAfter: PersistEvents后触发,捕获输出事件
生产路径为空方法体,零行为影响。
3. 移植RecordingSwapFlowEventService(借鉴testable分支):
override OnAfterMergePageEvent录制golden文件,备用录制工具。
内联GoldenFileModel(简单POCO)。FullRecord_WithPreBookingPositions连库测试自动跳过。
SwapModule 171测试全绿,无回归。
|
2026-07-03 09:38:05 +08:00 |
|
hjhan
|
f0ef37b599
|
test(swap): SwapFlowEventService seam改造+MergePageEventScenarioTest(6场景全绿)
借鉴 testable 分支,只取 seam(排除 PosiPnl/NetSettmentAmount 公式改动和 MergePageEvent 拆分),
填补当前分支对开平仓合成(MergePageEvent)零覆盖的空白。
SwapFlowEventService 新增11个 protected virtual seam:
- FindTrade/FindTradeExtend/FindPositions/FindAndInvalidateFutureEvents
- GetUnderlying/GetNextBusinessDay/ResolvePositionId
- PersistEvents(替代InitEvent内联Add+SaveChanges)/BeginTransaction/CommitTransaction/RollbackTransaction
MergePageEvent/InitEvent: private→protected virtual,内联DB调用替换为seam。
InitEvent 移除 DbContext.swap_flow_event.Add(转入PersistEvents,纯函数化)。
SwapTradeBaseService.UpdateDbOption: public void→public virtual(测试override用)。
新增测试(借鉴testable分支):
- TestableSwapFlowEventService.cs(集中式共享包装类)
- MergePageEventScenarioTest.cs(6场景全绿):
Scenario1 单条无持仓开仓 / Scenario2 同向追加 / Scenario3 反向全平
Scenario4 反向部分平+开 / Scenario5 一开一平 / Scenario6 复杂组合
**未借鉴**:SearchPositionFlowEvent的PosiPnl/NetSettmentAmount公式改动(行为变更)、
MergePageEvent拆分ProcessSingleFlow等(非必需重构)。
SwapModule 169测试全绿(+6),无回归。
|
2026-07-03 09:26:13 +08:00 |
|
hjhan
|
6e9bae94c5
|
test(swap): MergeRestModeCompose seam调用替换+移植MergeComposeScenarioTest(6/8场景)
借鉴 testable 分支,把 SwapTradeAutoService 的 MergeRestModeCompose/MergeRestModelItem/
DealNoPosition/DealHasPosition 内联DB调用替换为seam调用,生产行为不变。
替换的调用点:
- MergeRestModeCompose: FindActiveSwapTrades/FindTradeExtends/FindActivePositions/GetNextBusinessDayBefore/QueryFloatRates
- MergeRestModelItem: FindClient/GetEtradingRule/FindAssetUnit/FindUnderlying/GetSwapFloatRate/FindFlowEventsForCashCheck/FindValidTrades/SaveChanges
- DealNoPosition: CreateNewSwapTrade/AutoSwapUnwind
- DealHasPosition: AutoSwapUnwind
新增测试(借鉴testable分支):
- TestableSwapTradeAutoService.cs(集中式共享包装类)
- MergeComposeScenarioTest.cs(8场景):
Scenario1-5/8 通过: 客户/权限/账户/标的校验链 + 空流水返回
Scenario6/7 [Ignore]: 创建交易路径,DealNoPosition内部实现细节待对齐后启用
SwapModule 163测试全绿(+6),无回归。
|
2026-07-03 09:20:59 +08:00 |
|
hjhan
|
6b24e6e979
|
refactor(swap): SwapTradeAutoService补18个virtual seam(借鉴testable分支)
借鉴 origin/glms/feature/refactor-swap-event-testable 的可测性改造,
当前分支 SwapTradeAutoService 此前0个seam,纯新增#region可测试化区域,无冲突。
18个protected virtual seam(默认实现=原代码,行为不变):
- 日历: GetNextBusinessDay/GetNextBusinessDayBefore
- 计算: CalculateBondYtm
- 持久化: PersistMerge/SetModelOpt/SaveChanges
- 查询: FindActiveSwapTrades/FindTradeExtends/FindActivePositions/FindActivePositionsAll/
QueryFloatRates/FindClient/FindAssetUnit/FindUnderlying/FindFlowEventsForCashCheck/FindValidTrades
- 协作服务: GetEtradingRule/GetSwapFloatRate/CreateNewSwapTrade/AutoSwapUnwind
为后续 MergeComposeScenarioTest(自动簿记流程测试)铺路。
SwapModule 157测试全绿,seam未被override时按生产实现执行,行为不变。
|
2026-07-03 09:08:12 +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 |
|
hjhan
|
782e1f6a7a
|
refactor(swap): 债券价格÷100转换收敛到BondPriceConverter统一入口
消除9处价格转换字面量(*0.01m/*100),统一走BondPriceConverter.ToStorage/ToDisplay。
- 新增YLErpDAL/Helpers/BondPriceConverter.cs(含可空重载)
- 批次1(危险字面量): BondPaymentService/RealtimePnlCalc/RealTimeClientBanlanceService/SwapTradeAutoService
- 批次2-4(调用收敛): SwapFlowService/SwapFlowImportService/SwapEndConfirmService/EodPriceProvider/EodPriceQueryService
- RealtimePnlCalc:601/602价格×数量维度交织处加注释,不机械合并
不改bondPriceMultiple常量值,纯调用方式收敛。SwapModule 155测试全绿,行为不变。
|
2026-07-03 08:22:27 +08:00 |
|
张名锐
|
b2dce0e4f7
|
fix(swap): 修复互换交易流程事件数据填充问题
- 添加SwapTradeNo、EventType和EventReason字段到流程事件
- 修正EventType枚举类型从SwapEventTypeEnum改为SwapFlowEventTypeEnum
- 在SaveSwapDeal方法中添加交易信息验证逻辑
- 提取FillSwapFlowEvent方法统一处理流程事件数据填充
- 优化数据库保存操作确保数据一致性
|
2026-07-02 14:28:47 +08:00 |
|
锦麟 王
|
365711b5ff
|
自动互换分红时,期末结算全价使用PosiGrossPrice
|
2026-07-02 13:02:14 +08:00 |
|
hjhan
|
0910969e3f
|
fix(swap): PosiDividendSum精度差异修复(GLMS-20260105-0007)
问题:互换后PosiDividendSum=-89999.64(应为-90000),差0.36元。
根因:UpdateEodPosition cs:1635从头重算PosiDividendSum
(Round(全程,2)-已实现),与CopyEodPosition逐天递增
(每天Round(增量,2)累积)产生舍入误差累积。
修复:cs:1635改为递增模式
PosiDividendSum = eod.PosiDividendSum + TdPosiDividend - TdCloseDividend
与InterestIncomeSum的递增模式一致,避免从头重算的精度差异。
验证(golden录制/回放TDD):
- 真实数据录制GLMS-20260105-0007的eod快照+输入数据
- 回放重新调UpdateEodPosition:修复前=-89999.64(红灯),
修复后=-90000(绿灯,精确匹配)
- 121个测试全通过,无回归
|
2026-07-02 10:47:23 +08:00 |
|
hjhan
|
17005aa539
|
refactor(swap): ClearSwapPositions接缝-GetLegacyAutoSwapClientCashRecords可测化
SwapTradeBaseService加3个protected virtual虚方法:
- FindFlowEventsByEventIds: 查flow_event(原DbContext.swap_flow_event)
- FindManualClientCashIds: 查手动互换ClientCashId(原DbContext.swap_event)
- FindClientCashInCashOut: 查资金记录(原DbContext.ClientCashInCashOut)
GetLegacyAutoSwapClientCashRecords改为protected virtual,
内部3处DB查询替换为调虚方法。
这是78751f0a(重收盘误删资金修复)的核心逻辑:
GetLegacyAutoSwapClientCashRecords负责排除manualClientCashIds,
确保手动互换资金记录不被误删。
验证: 111个测试全通过。
|
2026-07-02 09:08:05 +08:00 |
|
hjhan
|
7c993f7bb2
|
refactor(swap): DealFloatPositions外部依赖虚方法接缝(分红场景准备)
加3个protected virtual虚方法:
- GetUnderlyingPrice: 标的市场价格(原UnderlyingCodePrice)
- GetUnderlyingData: 标的缓存数据(原DataCacheProvider)
- CalcBondPayment: 债券付息(原new BondPaymentService)
替换CopyEodPosition/UpdateEodPosition/SaveCurrentEodInitalPosi
内部的外部调用为调虚方法,生产代码行为不变。
这3个接缝使浮动腿归档的分红计算可测(TdPosiDividend/PosiDividendSum)。
验证: 108个测试全通过。
|
2026-07-02 08:57:55 +08:00 |
|
hjhan
|
4138a6ec36
|
refactor(swap): DealFloatPositions浮动腿归档方法可见性放开(testable迁移)
4个方法private→protected,不改变生产行为:
- DealFloatPositions(浮动腿归档主调度)
- CopyEodPosition(无平仓复制前日)
- UpdateEodPosition(有平仓更新)
- SaveCurrentEodInitalPosi(首日初始化)
这4个方法本身无直接DB调用(数据从参数传入),
但CopyEodPosition/UpdateEodPosition依赖外部数据源
(UnderlyingCodePrice/BondPaymentService/DataCacheProvider),
需后续加接缝才能完整测试。
SaveCurrentEodInitalPosi是纯计算可直接测。
验证: 104个测试全通过。
|
2026-07-02 08:47:30 +08:00 |
|
hjhan
|
7f0529bbed
|
test(swap): ComposePage流水合成持仓合成测试(testable迁移)
新增4个ComposePage场景测试(参考testable分支ComposePageScenarioTest):
- CP_001: 空事件→不创建持仓
- CP_002: 单条开仓→创建1条持仓,均价=开仓价
- CP_003: 两条开仓(同标的)→加权均价
- CP_004: 开仓+平仓→平仓扣减数量+产生资金记录
改动(SwapEodPositionService.cs):
- SaveEodPosition改为protected virtual(可override绕过UpdateSwapPosition连库)
- SaveEodPosition内部DbContext.Add替换为PersistEodSwapPosition
StubEodPositionService override 12个虚方法:
FindTrade/FindTradeExtend/FindEodSwapPositions/FindSwapPositions/
FindEodSwap/AddSwapEvent/AddClientCash/SaveEodSwapRecord/
ClearSwapPositionsForCompose/PersistEodSwapPosition/SaveAllChanges/
GetCurrencyRate + SaveEodPosition
验证: 100+4=104全通过(T0/T1=89+DealInterests=7+ConsumedInterest=4+ComposePage=4)。
|
2026-07-02 08:39:39 +08:00 |
|
hjhan
|
886a4d3ab1
|
refactor(swap): ComposePage补充接缝-AddClientCash/SaveEodSwapRecord/ClearSwapPositionsForCompose
ComposePage内部还有3处DB依赖需要接缝:
- AddClientCashInCashOut(cs:804平仓资金记录) → AddClientCash虚方法
- SaveEodSwap(cs:862框架合约汇总) → SaveEodSwapRecord虚方法
- ClearSwapPositions(cs:729清理旧事件) → ClearSwapPositionsForCompose虚方法
测试时override这3个虚方法可避免连库。
验证: 100个测试全通过。
|
2026-07-02 08:34:49 +08:00 |
|
hjhan
|
014edaed45
|
refactor(swap): ComposePage接缝-7虚方法+DB调用替换(testable迁移)
ComposePage(流水合成持仓)是swap_flow_event→swap_position的核心转换,
每笔开仓/平仓/互换都经过这里(176行)。
新增7个protected virtual虚方法(Seams):
- FindTrade/FindTradeExtend/FindSwapPositions
- FindEodSwapPositions/FindEodSwap
- AddSwapEvent/ExecuteInTransaction
ComposePage内部DB调用替换为调虚方法:
- DbContext.trade.Find → FindTrade
- DbContext.trade_extend.FirstOrDefault → FindTradeExtend
- DbContext.eod_swap_position.Where → FindEodSwapPositions
- DbContext.swap_position.Where → FindSwapPositions
- DbContext.eod_swap.FirstOrDefault → FindEodSwap
- new SwapEventService.AddSwapEventDate → AddSwapEvent
- DbContext.SaveChanges → SaveAllChanges(已有)
- ComposePage可见性private→protected
生产代码行为不变(虚方法默认实现=原逻辑)。
验证: 100个测试全通过(T0/T1=89+DealInterests=7+ConsumedInterest=4)。
|
2026-07-02 08:28:13 +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 |
|
hjhan
|
638803c497
|
refactor(swap): 阶段1c CalcSwapInterests虚方法接缝(testable迁移)
加1个protected virtual虚方法:
- CalcSwapInterests: 计算利息腿利息明细(原new SwapDealService(this).GetInterests)
参数与GetInterests完全一致,保证行为不变
将3个分支方法里的'new SwapDealService(this).GetInterests'替换为
调用CalcSwapInterests虚方法:
- SaveAutoEodInterestPosition(自动互换分支)
- SaveAutoEodWithCloseInterestPosition(平仓分支)
- SaveEodInterestPositionCopy(普通日分支)
测试子类override CalcSwapInterests,用StubSwapDealService
(已有89个测试验证)内存算利息,即可测全部4个分支。
验证: 93个测试全通过(T0/T1=89 + DealInterests=4),无回归。
|
2026-07-01 18:17:47 +08:00 |
|
hjhan
|
dc3a6e9f77
|
refactor(swap): 阶段1b SwapEodPositionService加虚方法接缝(testable迁移)
加3个protected virtual虚方法(Seams接缝),不改变生产行为:
- PersistEodSwapPosition: 持久化eod持仓(原DbContext.Add+UpdateDbOption)
- SaveAllChanges: 保存变更(原DbContext.SaveChanges)
- GetCurrencyRate: 获取汇率(原new EodCurrencyRateService)
将4个利息归档分支方法里的直接DB调用替换为调虚方法:
- SaveEodInterestPosition(互换分支)
- SaveAutoEodInterestPosition(自动互换分支)
- SaveAutoEodWithCloseInterestPosition(平仓分支)
- SaveEodInterestPositionCopy(普通计息分支)
测试子类override这些虚方法即可在内存中运行收盘逻辑,
不连数据库。生产代码行为完全不变(虚方法默认实现=原逻辑)。
验证: GetInterestsUnitTest_T0/T1 89个测试全通过,无回归。
|
2026-07-01 17:21:56 +08:00 |
|