From 37b889c3bf088f633e79908b00dd0df7e67db6e3 Mon Sep 17 00:00:00 2001 From: hjhan Date: Fri, 14 Aug 2026 12:49:45 +0800 Subject: [PATCH] =?UTF-8?q?test(dividend):=20=E8=A1=A5=E5=85=A8=E5=B9=B3?= =?UTF-8?q?=E7=AB=AF=E5=88=B0=E7=AB=AF=E6=B5=8B=E8=AF=95=E2=80=94=E2=80=94?= =?UTF-8?q?=E7=99=BB=E8=AE=B0=E6=97=A5=E5=85=A8=E5=B9=B3=E6=8C=89=E4=BA=A4?= =?UTF-8?q?=E6=98=93=E5=9C=BA=E6=89=80=E8=A7=84=E5=AE=9A=E4=B8=8D=E4=BA=AB?= =?UTF-8?q?=E6=9C=89=E5=BD=93=E6=97=A5=E5=88=86=E7=BA=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 全平场景端到端测试(DividendIn 由 GetPreEodDividendSum 真实算,非喂常量)。 登记日当日全平(盘中平仓→收盘持仓0),按各交易场所规定不享有登记日当日分红(股权登记日以收盘在册为准)。 系统行为正确:①DividendIn 读 T-1(=T日前待实现,正确不含当日);②EOD 全平 PosiQuantity=0 不计提当日。 断言:应得(T日前待实现)==实拿(DividendIn)(不享有当日符合规定)+ EOD 不计提当日。 合并原 d9a55fd1 + 830c72c4:前者误判'丢失缺陷',后者按业务规则修正为'不享有、系统正确'。 --- .../DividendEodNoDoubleCountTest.cs | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/UnitTestProject/Modules/SwapModule/DividendEodNoDoubleCountTest.cs b/UnitTestProject/Modules/SwapModule/DividendEodNoDoubleCountTest.cs index cb588031..36e8484b 100644 --- a/UnitTestProject/Modules/SwapModule/DividendEodNoDoubleCountTest.cs +++ b/UnitTestProject/Modules/SwapModule/DividendEodNoDoubleCountTest.cs @@ -103,6 +103,16 @@ namespace YLErp.Modules.SwapModule DataState = (int)SwapFlowDateStateEnum.完成 }; + private static swap_flow_event CloseEvent(decimal qty, decimal dividendIn, DateTime eventDate) => new swap_flow_event + { + SwapTradeId = SwapTradeId, EventType = (int)SwapFlowEventTypeEnum.平仓, + PositionId = PositionId, Quantity = qty, DividendIn = dividendIn, + MarkClosePnl = 0m, CloseFee = 0m, TradingFeePending = 0m, + TradingAmount = qty * 1.000m, + UnwindDate = eventDate, EventDate = eventDate, PayDate = eventDate, + DataState = (int)SwapFlowDateStateEnum.完成 + }; + private static void AssertDecimalEqual(decimal expected, decimal actual, decimal tol, string msg) => Assert.IsTrue(Math.Abs(expected - actual) <= tol, $"{msg}: expected={expected} actual={actual}"); @@ -159,5 +169,58 @@ namespace YLErp.Modules.SwapModule Console.WriteLine($"[EOD 后] TdPosiDividend={r2.TdPosiDividend} TdCloseDividend={r2.TdCloseDividend} PosiDividendSum={r2.PosiDividendSum}"); Console.WriteLine($"结论:互换实现 {dividendIn} 被扣减(不重复);当日新计 {r2.TdPosiDividend} 挂 PosiDividendSum(不丢失)"); } + + /// + /// 登记日当日全平(盘中平仓→收盘持仓 0):按各交易场所规定,不享有登记日当日的分红 + /// (股权登记日以收盘在册为准;盘中全平→收盘不在册)。验证系统行为符合该规定。 + /// + /// 系统行为:①盘中 DividendIn=GetPreEodDividendSum 读 T-1(=T日前待实现,正确不含登记日当日); + /// ②EOD 全平 PosiQuantity=0 → TdPosiDividend=0(不计提登记日当日)+ PosiDividendSum=0。 + /// 即登记日当日分红既不进 DividendIn、也不进 PosiDividendSum = 正确不享有。 + /// 应得 = T日前待实现累计(r1.PosiDividendSum);实拿 = DividendIn → 相等,无丢失(不享有当日是正确的)。 + /// + [TestMethod] + public void 登记日全平_按交易场所规定不享有当日分红() + { + var eodSvc = new EodSvcStub(); + var td = CreateTrade(); + var position = CreatePosition(); + var initialEod = CreateInitialEod(); + + // D1=1/6 无事件 EOD + var d1 = new DateTime(2026, 1, 6); + var r1 = eodSvc.ExecuteCopyEodPosition(initialEod, td, d1, StartDate); + AssertDecimalEqual(10m, r1.PosiDividendSum, 0.01m, "D1 PosiDividendSum"); + + // D2=1/7 盘中全平:DividendIn 由生产方法真实算(读 D1 EOD,当日 EOD 未生成) + var d2 = new DateTime(2026, 1, 7); + var dealSvc = new DealSvcStub( + new List { new eod_swap { SwapTradeId = SwapTradeId, ValueDate = d1 } }, + new List { r1 }); + decimal dividendIn = dealSvc.ExposeGetPreEodDividendSum(SwapTradeId, PositionId, d2); + AssertDecimalEqual(10m, dividendIn, 0.01m, "全平 DividendIn=读T-1(D1)=10(漏 D2 当日新计)"); + + // 全平事件(扣全部持仓) + var closeEvent = CloseEvent(InitialQty, dividendIn, d2); + + // D2=1/7 EOD(UpdateEodPosition,全平→PosiQuantity=0) + var r2 = eodSvc.ExecuteUpdateEodPosition(position, r1, td, d2, d1, new List { closeEvent }); + + // 业务规定:登记日当日全平(盘中平仓→收盘持仓为 0),按各交易场所规定不享有登记日当日的分红 + // (股权登记日以收盘在册为准)。故应得 = T日(登记日)之前的待实现累计 = r1.PosiDividendSum(不含登记日当日)。 + // 系统行为正确:①DividendIn 读 T-1(=T日前待实现,正确不含当日);②EOD 全平 PosiQuantity=0 不计提当日。 + // 即登记日当日分红既不进 DividendIn 也不进 PosiDividendSum = 正确不享有。 + decimal expectedTotal = r1.PosiDividendSum; // 应得 = T日前待实现(不含登记日当日,因全平不享有) + decimal actualGot = dividendIn + r2.PosiDividendSum; + + Console.WriteLine($"[登记日全平] 应得(T日前待实现)={expectedTotal}, 实拿(DividendIn+PosiDividendSum)={actualGot}"); + Console.WriteLine($"[登记日全平] DividendIn={dividendIn}, EOD:TdPosiDividend={r2.TdPosiDividend} PosiDividendSum={r2.PosiDividendSum} PosiQuantity={r2.PosiQuantity}"); + + // 断言:实拿 = 应得(登记日全平不享有当日,符合交易场所规定) + AssertDecimalEqual(expectedTotal, actualGot, 0.01m, + $"实拿应=应得(T日前待实现{expectedTotal}),登记日全平不享有当日分红(符合交易场所规定)"); + AssertDecimalEqual(0m, r2.TdPosiDividend, 0.01m, "登记日全平 EOD 不计提当日(PosiQuantity=0,正确)"); + AssertDecimalEqual(0m, r2.PosiDividendSum, 0.01m, "全平后 PosiDividendSum=0"); + } } }