From cbe5b58577f9a2bade955205c70d6be89670ed07 Mon Sep 17 00:00:00 2001 From: hjhan Date: Tue, 11 Aug 2026 12:30:53 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=96=B0=E5=A2=9E=20DirectionRatio?= =?UTF-8?q?=20=E6=96=B9=E5=90=91=E5=9B=A0=E5=AD=90=E7=BA=AF=E5=87=BD?= =?UTF-8?q?=E6=95=B0,=20=E6=9B=BF=E6=8D=A27=E5=A4=84=E4=B8=89=E5=85=83?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 多空方向(PositionType==Long?1:-1)和收付方向(xxx==收取?1:-1) 在两个上帝类里重复 15+处, +1/-1 写反是常见 bug 源。 新增 ReturnLegs/DirectionRatio.cs: - LongShort(positionType): 多头=+1, 空头=-1 - ReceivePay(direction): 收取=+1, 支付=-1 替换: - SwapEodPositionService: 6处 shortRatio 三元式(含注释1处) - SwapDealService: 1处 shortRatio + 1处 directionRatio 验证: 编译0错误, 全量511测试7失败(基线一致)。 --- .../ReturnLegs/DirectionRatioTest.cs | 27 +++++++++++++++++++ .../SwapModule/ReturnLegs/DirectionRatio.cs | 22 +++++++++++++++ .../Modules/SwapModule/SwapDealService.cs | 4 +-- .../SwapModule/SwapEodPositionService.cs | 10 +++---- 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 UnitTestProject/Modules/SwapModule/ReturnLegs/DirectionRatioTest.cs create mode 100644 YLErpDAL/Modules/SwapModule/ReturnLegs/DirectionRatio.cs diff --git a/UnitTestProject/Modules/SwapModule/ReturnLegs/DirectionRatioTest.cs b/UnitTestProject/Modules/SwapModule/ReturnLegs/DirectionRatioTest.cs new file mode 100644 index 00000000..ac36a4f2 --- /dev/null +++ b/UnitTestProject/Modules/SwapModule/ReturnLegs/DirectionRatioTest.cs @@ -0,0 +1,27 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using YLErp.DBModels; +using YLErp.DBModels.Enums; +using YLErp.Modules.SwapModule.ReturnLegs; + +namespace UnitTestProject.Modules.SwapModule.ReturnLegs +{ + [TestClass] + public class DirectionRatioTest + { + [TestMethod] + public void LongShort_多头_返回1() + => Assert.AreEqual(1, DirectionRatio.LongShort((int)PositionTypeFlag.Long)); + + [TestMethod] + public void LongShort_空头_返回负1() + => Assert.AreEqual(-1, DirectionRatio.LongShort((int)PositionTypeFlag.Short)); + + [TestMethod] + public void ReceivePay_收取_返回1() + => Assert.AreEqual(1, DirectionRatio.ReceivePay((int)SwapDirectionEnum.收取)); + + [TestMethod] + public void ReceivePay_支付_返回负1() + => Assert.AreEqual(-1, DirectionRatio.ReceivePay((int)SwapDirectionEnum.支付)); + } +} diff --git a/YLErpDAL/Modules/SwapModule/ReturnLegs/DirectionRatio.cs b/YLErpDAL/Modules/SwapModule/ReturnLegs/DirectionRatio.cs new file mode 100644 index 00000000..13808855 --- /dev/null +++ b/YLErpDAL/Modules/SwapModule/ReturnLegs/DirectionRatio.cs @@ -0,0 +1,22 @@ +using YLErp.DBModels; +using YLErp.DBModels.Enums; + +namespace YLErp.Modules.SwapModule.ReturnLegs; + +/// +/// 方向因子计算。把 PositionType / SwapDirection 转成 +1/-1 乘数。 +/// +/// 多空方向(Long/Short)和收付方向(收取/支付)在代码里反复写成三元表达式, +/// 散落在 SwapEodPositionService 15处 + SwapDealService 多处。 +/// 收敛到统一方法, 消除 +1/-1 写反的风险。 +/// +public static class DirectionRatio +{ + /// 多空方向因子。多头=+1, 空头=-1。 + public static int LongShort(int positionType) + => positionType == (int)PositionTypeFlag.Long ? 1 : -1; + + /// 收付方向因子。收取=+1, 支付=-1。 + public static int ReceivePay(int direction) + => direction == (int)SwapDirectionEnum.收取 ? 1 : -1; +} diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs index ba511cd9..99d25b3e 100644 --- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs @@ -1798,8 +1798,8 @@ namespace YLErp.Modules.SwapModule BondPaymentService servie = new BondPaymentService(UserInfo); var payments = servie.GetBondPayments(flowEvent.UnderlyingCode, td.StartDate.Value, date); - int shortRatio = flowEvent.PositionType == (int)PositionTypeFlag.Long ? 1 : -1; - int directionRatio = flowEvent.PayDirection == (int)SwapDirectionEnum.收取 ? 1 : -1; + int shortRatio = DirectionRatio.LongShort(flowEvent.PositionType); + int directionRatio = DirectionRatio.ReceivePay(flowEvent.PayDirection); // + 付息日>上日日终且小于等于平仓日期的分红数据 var dividendIn = servie.CalcPayment(payments, unwindQty, shortRatio, directionRatio); var um = DataCacheProvider.GetUnderlyingDataSource().GetData(flowEvent.UnderlyingCode); diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index c9da80f1..4aa6adc0 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -1693,7 +1693,7 @@ namespace YLErp.Modules.SwapModule { payQty = Math.Abs(payQty); int ratio = eventFlow.PayDirection == (int)SwapDirectionEnum.收取 ? 1 : -1;//收取为正,支付为负 - int shortRatio = newEodPayPosition.PositionType == (int)PositionTypeFlag.Long ? 1 : -1;//多空方向 + int shortRatio = DirectionRatio.LongShort(newEodPayPosition.PositionType); newEodPayPosition.ValueDate = eventFlow.PayDate.Value; newEodPayPosition.PositionId = eventFlow.PositionId; newEodPayPosition.ClientId = td.ClientId; @@ -1791,7 +1791,7 @@ namespace YLErp.Modules.SwapModule return curretEod; } var dealDate = curretEod.ValueDate; - int shortRatio = eod.PositionType == (int)PositionTypeFlag.Long ? 1 : -1; + int shortRatio = DirectionRatio.LongShort(eod.PositionType); int directionRatio = eod.PosiDirection == (int)SwapDirectionEnum.收取 ? 1 : -1; curretEod.PosiStatus = curretEod.PosiQuantity == 0 ? 1 : 0; var price = GetSwapValuationPrice(eod.UnderlyingCode, dealDate, out decimal vobp); @@ -1883,7 +1883,7 @@ namespace YLErp.Modules.SwapModule return curretEod; } var dealDate = curretEod.ValueDate; - int shortRatio = eod.PositionType == (int)PositionTypeFlag.Long ? 1 : -1; + int shortRatio = DirectionRatio.LongShort(eod.PositionType); int directionRatio = eod.PosiDirection == (int)SwapDirectionEnum.收取 ? 1 : -1; var price = GetSwapValuationPrice(eod.UnderlyingCode, dealDate, out decimal vobp); var todayConsumedDividend = CalcConsumedDividend(curretEod, unwindEvents); @@ -1971,7 +1971,7 @@ namespace YLErp.Modules.SwapModule { return; } - int shortRatio = eod.PositionType == (int)PositionTypeFlag.Long ? 1 : -1; + int shortRatio = DirectionRatio.LongShort(eod.PositionType); int directionRatio = eod.PosiDirection == (int)SwapDirectionEnum.收取 ? 1 : -1; var unwindFlowEvents = unwindEvents.Where(x => x.EventType == (int)SwapFlowEventTypeEnum.平仓).ToList(); var openFlowEvents = unwindEvents.Where(x => x.EventType == (int)SwapFlowEventTypeEnum.开仓).ToList(); @@ -2052,7 +2052,7 @@ namespace YLErp.Modules.SwapModule curretEod.SwapTradeId = td.id; curretEod.PositionId = position.id; curretEod.ClientId = td.ClientId; - int shortRatio = position.PositionType == (int)PositionTypeFlag.Long ? 1 : -1; + int shortRatio = DirectionRatio.LongShort(position.PositionType); int directionRatio = position.PosiDirection == (int)SwapDirectionEnum.收取 ? 1 : -1; curretEod.PositionType = position.PositionType; var eod = new eod_swap_position()