From 16c44d3b500de2eb8a80ad4804d6bfc0cd7dcc84 Mon Sep 17 00:00:00 2001 From: hjhan Date: Tue, 11 Aug 2026 16:50:21 +0800 Subject: [PATCH] =?UTF-8?q?refactor(return-leg):=20=E6=8A=BD=E5=8F=96=20Po?= =?UTF-8?q?sitionValueCalc=20=E6=8C=81=E4=BB=93=E4=BB=B7=E5=80=BC=E6=B1=87?= =?UTF-8?q?=E6=80=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SwapEodPositionService 8处 SwapPositionValue inline 公式替换: - 4处 InterestProfitSum * ratio + PosiProfitSum → PositionValueCalc.Calc(带ratio) - 4处 InterestProfitSum + PosiProfitSum → PositionValueCalc.Calc(默认ratio=1) 持仓价值 = 利息端收益 + 浮动端收益, 8处副本→1个纯函数。 这是最后一个高性价比的纯函数提取。 验证: 编译0错误, 全量513测试7失败(基线一致)。 --- .../ReturnLegs/PositionValueCalcTest.cs | 25 +++++++++++++++++++ .../ReturnLegs/PositionValueCalc.cs | 15 +++++++++++ .../SwapModule/SwapEodPositionService.cs | 16 ++++++------ 3 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 UnitTestProject/Modules/SwapModule/ReturnLegs/PositionValueCalcTest.cs create mode 100644 YLErpDAL/Modules/SwapModule/ReturnLegs/PositionValueCalc.cs diff --git a/UnitTestProject/Modules/SwapModule/ReturnLegs/PositionValueCalcTest.cs b/UnitTestProject/Modules/SwapModule/ReturnLegs/PositionValueCalcTest.cs new file mode 100644 index 00000000..d65db05d --- /dev/null +++ b/UnitTestProject/Modules/SwapModule/ReturnLegs/PositionValueCalcTest.cs @@ -0,0 +1,25 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using YLErp.Modules.SwapModule.ReturnLegs; + +namespace UnitTestProject.Modules.SwapModule.ReturnLegs +{ + [TestClass] + public class PositionValueCalcTest + { + [TestMethod] + public void 无方向因子_利息加浮动() + => Assert.AreEqual(1500m, PositionValueCalc.Calc(1000m, 500m)); + + [TestMethod] + public void 收取方向_利息乘1() + => Assert.AreEqual(1500m, PositionValueCalc.Calc(1000m, 500m, 1m)); + + [TestMethod] + public void 支付方向_利息乘负1() + => Assert.AreEqual(-500m, PositionValueCalc.Calc(1000m, 500m, -1m)); + + [TestMethod] + public void 零利息_等于浮动端() + => Assert.AreEqual(500m, PositionValueCalc.Calc(0m, 500m)); + } +} diff --git a/YLErpDAL/Modules/SwapModule/ReturnLegs/PositionValueCalc.cs b/YLErpDAL/Modules/SwapModule/ReturnLegs/PositionValueCalc.cs new file mode 100644 index 00000000..dd4a4d2d --- /dev/null +++ b/YLErpDAL/Modules/SwapModule/ReturnLegs/PositionValueCalc.cs @@ -0,0 +1,15 @@ +namespace YLErp.Modules.SwapModule.ReturnLegs; + +/// +/// 持仓价值(SwapPositionValue)汇总。 +/// +/// SwapPositionValue = 利息端收益 + 浮动端收益。 +/// 利息端可能带方向因子(收取/支付),浮动端不含方向因子。 +/// 原代码在 SwapEodPositionService 8处重复此公式(1115/1258/1519/1647/1746/1830/1938/2113)。 +/// +public static class PositionValueCalc +{ + /// 持仓价值 = 利息端 × 方向因子 + 浮动端。 + public static decimal Calc(decimal interestProfitSum, decimal posiProfitSum, decimal ratio = 1m) + => interestProfitSum * ratio + posiProfitSum; +} diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index 4aa6adc0..9d5f345b 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 = newEodPayPosition.InterestProfitSum * ratio + newEodPayPosition.PosiProfitSum; + newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, 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 = newEodPayPosition.InterestProfitSum * ratio + newEodPayPosition.PosiProfitSum; + newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, 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 = newEodPayPosition.InterestProfitSum * ratio + newEodPayPosition.PosiProfitSum; + newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, 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 = newEodPayPosition.InterestProfitSum * ratio + newEodPayPosition.PosiProfitSum; + newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, ratio); //累计已实现 newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; @@ -1743,7 +1743,7 @@ namespace YLErp.Modules.SwapModule newEodPayPosition.PosiProfitSum = newEodPayPosition.PosiMtmPnL + newEodPayPosition.PosiDividendSum + newEodPayPosition.PosiFeePending; //持仓价值 - newEodPayPosition.SwapPositionValue = newEodPayPosition.InterestProfitSum + newEodPayPosition.PosiProfitSum; + newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum); //累计已实现 newEodPayPosition.RealizedFee = closeFee; newEodPayPosition.RealizedMtmPnL = newEodPayPosition.TdCloseMtmPnl; @@ -1827,7 +1827,7 @@ namespace YLErp.Modules.SwapModule , seekPreday: true, currencyRateType: curretEod.PosiDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); curretEod.TdCurrency = Convert.ToDecimal(currencyRate); //持仓价值 - curretEod.SwapPositionValue = curretEod.InterestProfitSum + curretEod.PosiProfitSum; + curretEod.SwapPositionValue = PositionValueCalc.Calc(curretEod.InterestProfitSum, curretEod.PosiProfitSum); UpdateDbOption(curretEod); curretEod.Invalid = false; if (curretEod.id == 0) @@ -1935,7 +1935,7 @@ namespace YLErp.Modules.SwapModule , seekPreday: true, currencyRateType: curretEod.PosiDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); curretEod.TdCurrency = Convert.ToDecimal(currencyRate); //持仓价值 - curretEod.SwapPositionValue = curretEod.InterestProfitSum + curretEod.PosiProfitSum; + curretEod.SwapPositionValue = PositionValueCalc.Calc(curretEod.InterestProfitSum, curretEod.PosiProfitSum); UpdateDbOption(curretEod); curretEod.Invalid = false; if (curretEod.id == 0) @@ -2110,7 +2110,7 @@ namespace YLErp.Modules.SwapModule curretEod.PosiNotionalValue = 0; } //持仓价值 - curretEod.SwapPositionValue = curretEod.InterestProfitSum + curretEod.PosiProfitSum; + curretEod.SwapPositionValue = PositionValueCalc.Calc(curretEod.InterestProfitSum, curretEod.PosiProfitSum); var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, td.StartDate.Value , seekPreday: true, currencyRateType: curretEod.PosiDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); curretEod.TdCurrency = Convert.ToDecimal(currencyRate);