diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs index 367cef46..376aa685 100644 --- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs @@ -1326,6 +1326,19 @@ namespace YLErp.Modules.SwapModule return interest; } + /// + /// 按 interest_rule 取 FR007 定盘价。无浮动标的时返回 fallback;取不到抛异常。 + /// EOD 单日取率 + BuildSegmentRates 多日取率共用此方法,FR007 定盘逻辑收口到一处。 + /// + private decimal ResolveFloatRate(swap_position position, DateTime date, decimal fallback) + { + if (string.IsNullOrEmpty(position.FloatRateUnderlyingCode)) return fallback; + var fixingDate = IndexFixerBase.GetFixingDate(date, position.interest_rule); + if (IndexFixer.TryGetFixing(fixingDate, position.FloatRateUnderlyingCode, out decimal fixing)) + return fixing != 0m ? fixing : fallback; + throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fixingDate:yyyy年MM月dd日}的价格"); + } + /// /// 按重置周期切分利率段,每段记录 all-in 利率(spread+fixing)。返回 (分段列表, 末段浮动利率)。 /// fetchAfterDate: 仅该日期之后的重置日才取 FR007(单利传 ValueDate,复利传 null 全程取)。 @@ -1341,19 +1354,8 @@ namespace YLErp.Modules.SwapModule for (int i = 0; i <= calcDays; i += interestPeriod) { var resetDate = startDate.AddDays(i); - if ((fetchAfterDate == null || resetDate > fetchAfterDate.Value) - && !string.IsNullOrEmpty(position.FloatRateUnderlyingCode)) - { - var fixingDate = IndexFixerBase.GetFixingDate(resetDate, position.interest_rule); - if (IndexFixer.TryGetFixing(fixingDate, position.FloatRateUnderlyingCode, out decimal fixing)) - { - if (fixing != 0m) currentFloat = fixing; - } - else - { - throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fixingDate:yyyy年MM月dd日}的价格"); - } - } + if (fetchAfterDate == null || resetDate > fetchAfterDate.Value) + currentFloat = ResolveFloatRate(position, resetDate, currentFloat); rates.Add((resetDate, spread + currentFloat)); } return (rates, currentFloat); @@ -1467,19 +1469,7 @@ namespace YLErp.Modules.SwapModule // 重置日按 interest_rule 重新定盘浮动利率(GLMS-JIATT-20260805 根因—— // 重置日=平仓日必须用新利率,否则沿用旧周期利率并污染后续 EOD)。非重置日沿用 floateRate。 - decimal effectiveFloat = floateRate; - if (isResetDay && !string.IsNullOrEmpty(position.FloatRateUnderlyingCode)) - { - var fixingDate = IndexFixerBase.GetFixingDate(endDate, position.interest_rule); - if (IndexFixer.TryGetFixing(fixingDate, position.FloatRateUnderlyingCode, out decimal fixing)) - { - if (fixing != 0m) effectiveFloat = fixing; - } - else - { - throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fixingDate:yyyy年MM月dd日}的价格"); - } - } + var effectiveFloat = isResetDay ? ResolveFloatRate(position, endDate, floateRate) : floateRate; flowEvent.FloatRate = effectiveFloat; // remainingFraction:重置日把上一日终待实现利息按本次平仓基数分摊(EOD 全量为 1)。 @@ -1537,21 +1527,9 @@ namespace YLErp.Modules.SwapModule // 取率:重置日按 interest_rule 重新定盘浮动利率(GLMS-JIATT-20260805 根因—— // 重置日=平仓日必须用新利率,否则沿用旧周期利率并污染后续 EOD)。 - decimal effectiveFloat = floateRate; int interestPeriod = position.interest_rest_days ?? 1; - if ((endDate - tradeDate).Days % interestPeriod == 0 - && !string.IsNullOrEmpty(position.FloatRateUnderlyingCode)) - { - var fixingDate = IndexFixerBase.GetFixingDate(endDate, position.interest_rule); - if (IndexFixer.TryGetFixing(fixingDate, position.FloatRateUnderlyingCode, out decimal fixing)) - { - if (fixing != 0m) effectiveFloat = fixing; - } - else - { - throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fixingDate:yyyy年MM月dd日}的价格"); - } - } + var isResetDay = (endDate - tradeDate).Days % interestPeriod == 0; + var effectiveFloat = isResetDay ? ResolveFloatRate(position, endDate, floateRate) : floateRate; flowEvent.FloatRate = effectiveFloat;