diff --git a/Framework/YLErp.Core/DBModels/EodSwapPosition.cs b/Framework/YLErp.Core/DBModels/EodSwapPosition.cs index f4c8f745..77b3dbbf 100644 --- a/Framework/YLErp.Core/DBModels/EodSwapPosition.cs +++ b/Framework/YLErp.Core/DBModels/EodSwapPosition.cs @@ -205,7 +205,7 @@ namespace YLErp.DBModels [DataChange] public int InterestDirection { get; set; } /// - /// 计息基本类型 1:固定值,2:合约名义本金规模,3:持仓名义本金,4:持仓市值,5:初始预付金,6:追加预付金 + /// 计息基本类型 1:固定值,2:合约名义本金规模,5:初始预付金,6:追加预付金,9:标的期初全价 /// [DisplayName("计息基本类型")] [DataChange] diff --git a/Framework/YLErp.Core/DBModels/SwapFlowEvent.cs b/Framework/YLErp.Core/DBModels/SwapFlowEvent.cs index 632ed8c3..b635b672 100644 --- a/Framework/YLErp.Core/DBModels/SwapFlowEvent.cs +++ b/Framework/YLErp.Core/DBModels/SwapFlowEvent.cs @@ -280,7 +280,7 @@ namespace YLErp.DBModels } } /// - /// 计息方式 1:固定值,2:合约名义本金规模,3:持仓名义本金,4:持仓市值 + /// 计息方式 1:固定值,2:合约名义本金规模,5:初始预付金,6:追加预付金,9:标的期初全价 /// [DisplayName("计息方式")] [DataChange] diff --git a/Framework/YLErp.Core/DBModels/SwapPosition.cs b/Framework/YLErp.Core/DBModels/SwapPosition.cs index 04a306f9..a5d66d81 100644 --- a/Framework/YLErp.Core/DBModels/SwapPosition.cs +++ b/Framework/YLErp.Core/DBModels/SwapPosition.cs @@ -163,7 +163,7 @@ namespace YLErp.DBModels /// public string FloatRateUnderlyingCode { get; set; } /// - /// 计息基本类型 1:固定值,2:合约名义本金规模,3:持仓名义本金,4:持仓市值,5:初始预付金,6:追加预付金 + /// 计息基本类型 1:固定值,2:合约名义本金规模,5:初始预付金,6:追加预付金,9:标的期初全价 /// [DisplayName("计息基本类型")] [DataChange] diff --git a/UnitTestProject/Modules/SwapModule/FundingLegs/FundingLegStrategyTest.cs b/UnitTestProject/Modules/SwapModule/FundingLegs/FundingLegStrategyTest.cs index c3afb09f..ebd0803f 100644 --- a/UnitTestProject/Modules/SwapModule/FundingLegs/FundingLegStrategyTest.cs +++ b/UnitTestProject/Modules/SwapModule/FundingLegs/FundingLegStrategyTest.cs @@ -6,16 +6,14 @@ using YLErp.Modules.SwapModule.FundingLegs; namespace UnitTestProject.Modules.SwapModule.FundingLegs { /// - /// 融资腿策略单测。验证每个策略的 CalcNotional 与现有 CalcNotionalByMode switch 完全一致。 - /// 这组测试是后续"迁移调用点"的安全网——迁移前后行为必须不变。 + /// 融资腿策略单测。验证每个 IFundingLegStrategy 实现的 CalcNotional 计息基数公式正确。 + /// 原 CalcNotionalByMode switch 已重构为策略类(见 FundingLegStrategyFactory)。 /// [TestClass] public class FundingLegStrategyTest { private const decimal Fix = 2_000_000m; private const decimal Notional = 100_000_000m; - private const decimal LongNotional = 60_000_000m; - private const decimal ShortNotional = 40_000_000m; #region 固定值(mode 1) @@ -23,7 +21,7 @@ namespace UnitTestProject.Modules.SwapModule.FundingLegs public void 固定值_部分平仓_计息基数恒等于Fix() { var leg = new FixedAmountLeg(); - var r = leg.CalcNotional(Fix, Notional, LongNotional, ShortNotional, 0.5m); + var r = leg.CalcNotional(Fix, Notional, 0.5m); Assert.AreEqual(Fix, r.ClosePrincipal, "平仓本金恒=Fix"); Assert.AreEqual(Fix, r.PosiPrincipal, "持仓本金恒=Fix"); @@ -34,7 +32,7 @@ namespace UnitTestProject.Modules.SwapModule.FundingLegs public void 固定值_全平_计息基数仍等于Fix() { var leg = new FixedAmountLeg(); - var r = leg.CalcNotional(Fix, Notional, LongNotional, ShortNotional, 1m); + var r = leg.CalcNotional(Fix, Notional, 1m); Assert.AreEqual(Fix, r.ClosePrincipal); } @@ -46,7 +44,7 @@ namespace UnitTestProject.Modules.SwapModule.FundingLegs public void 合约名义本金_部分平仓_本金按比例缩放() { var leg = new ContractNotionalLeg(); - var r = leg.CalcNotional(Fix, Notional, LongNotional, ShortNotional, 0.5m); + var r = leg.CalcNotional(Fix, Notional, 0.5m); Assert.AreEqual(50_000_000m, r.ClosePrincipal); Assert.AreEqual(Notional, r.PosiPrincipal); @@ -57,7 +55,7 @@ namespace UnitTestProject.Modules.SwapModule.FundingLegs public void 合约名义本金_全平_本金等于全额() { var leg = new ContractNotionalLeg(); - var r = leg.CalcNotional(Fix, Notional, LongNotional, ShortNotional, 1m); + var r = leg.CalcNotional(Fix, Notional, 1m); Assert.AreEqual(Notional, r.ClosePrincipal); } @@ -65,7 +63,7 @@ namespace UnitTestProject.Modules.SwapModule.FundingLegs public void 合约名义本金_零平仓_本金为零() { var leg = new ContractNotionalLeg(); - var r = leg.CalcNotional(Fix, Notional, LongNotional, ShortNotional, 0m); + var r = leg.CalcNotional(Fix, Notional, 0m); Assert.AreEqual(0m, r.ClosePrincipal); Assert.AreEqual(Notional, r.PosiPrincipal); @@ -79,7 +77,7 @@ namespace UnitTestProject.Modules.SwapModule.FundingLegs public void 标的期初全价_部分平仓_主路径公式同mode2() { var leg = new UnderlyingEntryFullPriceLeg(); - var r = leg.CalcNotional(Fix, Notional, LongNotional, ShortNotional, 0.5m); + var r = leg.CalcNotional(Fix, Notional, 0.5m); Assert.AreEqual(50_000_000m, r.ClosePrincipal); Assert.AreEqual(Notional, r.PosiPrincipal); @@ -90,7 +88,7 @@ namespace UnitTestProject.Modules.SwapModule.FundingLegs public void 标的期初全价_全平_本金等于全额() { var leg = new UnderlyingEntryFullPriceLeg(); - var r = leg.CalcNotional(Fix, Notional, LongNotional, ShortNotional, 1m); + var r = leg.CalcNotional(Fix, Notional, 1m); Assert.AreEqual(Notional, r.ClosePrincipal); } diff --git a/UnitTestProject/Modules/SwapModule/SwapUnwindFloatingLegDiagnosticTdd.cs b/UnitTestProject/Modules/SwapModule/SwapUnwindFloatingLegDiagnosticTdd.cs index 84a7230d..69f7ca72 100644 --- a/UnitTestProject/Modules/SwapModule/SwapUnwindFloatingLegDiagnosticTdd.cs +++ b/UnitTestProject/Modules/SwapModule/SwapUnwindFloatingLegDiagnosticTdd.cs @@ -5,12 +5,12 @@ using YLErp.DBModels.Enums; namespace YLErp.Modules.SwapModule { /// - /// 诊断测试:验证「浮动腿 fpositions 仍用 origPositions(orig 100M)」对本 deal 的 - /// 预付金/返回预付金结果是否产生影响。结论预期:本 deal 利息腿只有 mode 9(标的期初全价) - /// 与 mode 5(初始预付金),CalcNotionalByMode 中 posiLong/posiShort 仅在「多头/空头存续名义本金」 - /// 分支被消费(L709-716),故本 deal 即便 fpositions 用 orig 100M,预付金腿结果也不受其影响。 - /// 本测试仅做诊断/验证,不改动任何生产代码;用反射调用 private CalcNotionalByMode 以直接证明 - /// “mode 9 / mode 5 的 closePrincipal 不依赖 posiLong/posiShort”。 + /// 诊断测试骨架:针对 GLMS 双轨持仓(orig/real)构造预付金腿(mode 5)与标的期初全价腿(mode 9), + /// 用于验证“浮动腿 fpositions 用 origPositions 对预付金/标的端计息基数的影响”。 + /// 计息基数现由 FundingLegStrategyFactory + 各 IFundingLegStrategy 策略类计算 + /// (原 private CalcNotionalByMode 已重构移除);多空存续腿的 posiLong/posiShort 因界面禁用 + /// 已从策略接口删除,故预付金/标的端计息基数不依赖多空头寸。 + /// 注:当前仅含数据构造,反射诊断方法尚未实现(无 [TestMethod])。 /// [TestClass] public class SwapUnwindFloatingLegDiagnosticTdd diff --git a/YLErpDAL/Modules/SwapModule/FundingLegs/ContractNotionalLeg.cs b/YLErpDAL/Modules/SwapModule/FundingLegs/ContractNotionalLeg.cs index f1d62dd0..97e6faea 100644 --- a/YLErpDAL/Modules/SwapModule/FundingLegs/ContractNotionalLeg.cs +++ b/YLErpDAL/Modules/SwapModule/FundingLegs/ContractNotionalLeg.cs @@ -11,6 +11,6 @@ public sealed class ContractNotionalLeg : IFundingLegStrategy { public InterestModeEnum Mode => InterestModeEnum.合约名义本金规模; - public NotionalResult CalcNotional(decimal fix, decimal posiNotional, decimal posiLong, decimal posiShort, decimal closePercent) + public NotionalResult CalcNotional(decimal fix, decimal posiNotional, decimal closePercent) => new(posiNotional * closePercent, posiNotional, closePercent); } diff --git a/YLErpDAL/Modules/SwapModule/FundingLegs/FixedAmountLeg.cs b/YLErpDAL/Modules/SwapModule/FundingLegs/FixedAmountLeg.cs index 6e477b07..451384ec 100644 --- a/YLErpDAL/Modules/SwapModule/FundingLegs/FixedAmountLeg.cs +++ b/YLErpDAL/Modules/SwapModule/FundingLegs/FixedAmountLeg.cs @@ -12,6 +12,6 @@ public sealed class FixedAmountLeg : IFundingLegStrategy { public InterestModeEnum Mode => InterestModeEnum.固定值; - public NotionalResult CalcNotional(decimal fix, decimal posiNotional, decimal posiLong, decimal posiShort, decimal closePercent) + public NotionalResult CalcNotional(decimal fix, decimal posiNotional, decimal closePercent) => new(fix, fix, 1m); } diff --git a/YLErpDAL/Modules/SwapModule/FundingLegs/IFundingLegStrategy.cs b/YLErpDAL/Modules/SwapModule/FundingLegs/IFundingLegStrategy.cs index 2d29f8c0..9ef23074 100644 --- a/YLErpDAL/Modules/SwapModule/FundingLegs/IFundingLegStrategy.cs +++ b/YLErpDAL/Modules/SwapModule/FundingLegs/IFundingLegStrategy.cs @@ -22,10 +22,8 @@ public interface IFundingLegStrategy /// /// 合约固定本金(固定值/预付金腿用;其余腿忽略)。 /// 当前剩余名义本金(数量 × 全价)。 - /// 多头剩余名义本金(多空存续腿用,当前界面已禁用)。 - /// 空头剩余名义本金。 /// 平仓比例(占剩余,0~1)。 - NotionalResult CalcNotional(decimal fix, decimal posiNotional, decimal posiLong, decimal posiShort, decimal closePercent); + NotionalResult CalcNotional(decimal fix, decimal posiNotional, decimal closePercent); } /// diff --git a/YLErpDAL/Modules/SwapModule/FundingLegs/UnderlyingEntryFullPriceLeg.cs b/YLErpDAL/Modules/SwapModule/FundingLegs/UnderlyingEntryFullPriceLeg.cs index f78d9b74..6838f7e0 100644 --- a/YLErpDAL/Modules/SwapModule/FundingLegs/UnderlyingEntryFullPriceLeg.cs +++ b/YLErpDAL/Modules/SwapModule/FundingLegs/UnderlyingEntryFullPriceLeg.cs @@ -14,6 +14,6 @@ public sealed class UnderlyingEntryFullPriceLeg : IFundingLegStrategy { public InterestModeEnum Mode => InterestModeEnum.标的期初全价; - public NotionalResult CalcNotional(decimal fix, decimal posiNotional, decimal posiLong, decimal posiShort, decimal closePercent) + public NotionalResult CalcNotional(decimal fix, decimal posiNotional, decimal closePercent) => new(posiNotional * closePercent, posiNotional, closePercent); } diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs index bf9bbaa4..beeeef4e 100644 --- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs @@ -718,7 +718,7 @@ namespace YLErp.Modules.SwapModule { // 融资腿(1/2/9): 走策略工厂 var r = FundingLegStrategyFactory.Get(mode) - .CalcNotional(position.InterestPrincipalFix, posiNotionalValue, posiLongNotionalValue, posiShortNotionalValue, closePrecent); + .CalcNotional(position.InterestPrincipalFix, posiNotionalValue, closePrecent); closePrincipal = r.ClosePrincipal; posiPrincipal = r.PosiPrincipal; newClosePercent = r.ClosePercent;