From 5a7869e0c915966eda115dd4e3ef1cd8696661e1 Mon Sep 17 00:00:00 2001 From: hjhan Date: Tue, 11 Aug 2026 16:59:22 +0800 Subject: [PATCH] =?UTF-8?q?fix(return-leg):=20PositionValueCalc.ratio=20?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20int,=20=E7=BB=9F=E4=B8=80=E6=96=B9?= =?UTF-8?q?=E5=90=91=E5=9B=A0=E5=AD=90=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ratio(收取=1/支付=-1)是方向因子, 应该是 int。 和 MtmCalc/DirectionRatio/MarginCalc 的 int 保持一致。 调用点(SwapEodPositionService 4处)原 ratio 是 decimal, 加 (int) 显式转换(值恒为 1或-1, 零精度损失)。 排查确认: 这是唯一的类型不一致, 其他纯函数参数类型均已统一。 验证: 编译0错误, 全量513测试7失败(基线一致)。 --- .../SwapModule/ReturnLegs/PositionValueCalcTest.cs | 4 ++-- .../Modules/SwapModule/ReturnLegs/PositionValueCalc.cs | 4 ++-- YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/UnitTestProject/Modules/SwapModule/ReturnLegs/PositionValueCalcTest.cs b/UnitTestProject/Modules/SwapModule/ReturnLegs/PositionValueCalcTest.cs index d65db05d..26f1d27e 100644 --- a/UnitTestProject/Modules/SwapModule/ReturnLegs/PositionValueCalcTest.cs +++ b/UnitTestProject/Modules/SwapModule/ReturnLegs/PositionValueCalcTest.cs @@ -12,11 +12,11 @@ namespace UnitTestProject.Modules.SwapModule.ReturnLegs [TestMethod] public void 收取方向_利息乘1() - => Assert.AreEqual(1500m, PositionValueCalc.Calc(1000m, 500m, 1m)); + => Assert.AreEqual(1500m, PositionValueCalc.Calc(1000m, 500m, 1)); [TestMethod] public void 支付方向_利息乘负1() - => Assert.AreEqual(-500m, PositionValueCalc.Calc(1000m, 500m, -1m)); + => Assert.AreEqual(-500m, PositionValueCalc.Calc(1000m, 500m, -1)); [TestMethod] public void 零利息_等于浮动端() diff --git a/YLErpDAL/Modules/SwapModule/ReturnLegs/PositionValueCalc.cs b/YLErpDAL/Modules/SwapModule/ReturnLegs/PositionValueCalc.cs index dd4a4d2d..71484ba8 100644 --- a/YLErpDAL/Modules/SwapModule/ReturnLegs/PositionValueCalc.cs +++ b/YLErpDAL/Modules/SwapModule/ReturnLegs/PositionValueCalc.cs @@ -9,7 +9,7 @@ namespace YLErp.Modules.SwapModule.ReturnLegs; /// public static class PositionValueCalc { - /// 持仓价值 = 利息端 × 方向因子 + 浮动端。 - public static decimal Calc(decimal interestProfitSum, decimal posiProfitSum, decimal ratio = 1m) + /// 持仓价值 = 利息端 × 方向因子 + 浮动端。ratio: 收取=1, 支付=-1。 + public static decimal Calc(decimal interestProfitSum, decimal posiProfitSum, int ratio = 1) => interestProfitSum * ratio + posiProfitSum; } diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index 9d5f345b..c70476bb 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -1112,7 +1112,7 @@ namespace YLErp.Modules.SwapModule } newEodPayPosition.InterestProfitSum = newEodPayPosition.InterestIncomeSum + newEodPayPosition.InterestFeeSum; //持仓价值 - newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, ratio); + newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, (int)ratio); //累计已实现 newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; @@ -1255,7 +1255,7 @@ namespace YLErp.Modules.SwapModule : RoundEodInterest(eodPayPosition.InterestFeeSum + newEodPayPosition.TdInterestFee - newEodPayPosition.TdCloseInterestFee); newEodPayPosition.InterestProfitSum = newEodPayPosition.InterestIncomeSum + newEodPayPosition.InterestFeeSum; //持仓价值 - newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, ratio); + newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, (int)ratio); //累计已实现 newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; @@ -1516,7 +1516,7 @@ namespace YLErp.Modules.SwapModule // InterestProfitSum 是利息腿待实现总额,包含利息和费用;无费用时等于 InterestIncomeSum。 newEodPayPosition.InterestProfitSum = newEodPayPosition.InterestIncomeSum + newEodPayPosition.InterestFeeSum; //持仓价值 - newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, ratio); + newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, (int)ratio); Log.Info($"InterestIncomeSum is {eodPayPosition.InterestIncomeSum},TdInterestIncome is {newEodPayPosition.TdInterestIncome}" + $",TdCloseInterest is {newEodPayPosition.TdCloseInterest}"); @@ -1644,7 +1644,7 @@ namespace YLErp.Modules.SwapModule newEodPayPosition.InterestFeeSum = eodPayPosition.InterestFeeSum + newEodPayPosition.TdInterestFee - newEodPayPosition.TdCloseInterestFee; newEodPayPosition.InterestProfitSum = newEodPayPosition.InterestIncomeSum + newEodPayPosition.InterestFeeSum; //持仓价值 - newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, ratio); + newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, (int)ratio); //累计已实现 newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; @@ -1738,7 +1738,7 @@ namespace YLErp.Modules.SwapModule //持仓内容-浮动收益腿-损益统计(本方视角 newEodPayPosition.TdPosiDividend = Math.Round(dividendIn * ratio, 2); - newEodPayPosition.PosiMtmPnL = MtmCalc.UnrealizedPnl(newEodPayPosition.UnderlyingPrice, newEodPayPosition.PosiGrossPrice, newEodPayPosition.PosiQuantity, newEodPayPosition.ContractSize, shortRatio, ratio); + newEodPayPosition.PosiMtmPnL = MtmCalc.UnrealizedPnl(newEodPayPosition.UnderlyingPrice, newEodPayPosition.PosiGrossPrice, newEodPayPosition.PosiQuantity, newEodPayPosition.ContractSize, shortRatio, (int)ratio); newEodPayPosition.PosiDividendSum = Math.Round(newEodPayPosition.TdPosiDividend - newEodPayPosition.TdCloseDividend, 2); newEodPayPosition.PosiProfitSum = newEodPayPosition.PosiMtmPnL + newEodPayPosition.PosiDividendSum + newEodPayPosition.PosiFeePending;