refactor(accrual): 提取ResolveFloatRate收口FR007定盘逻辑
EOD单日取率(CompoundEod/SimpleEod)与intraday多日取率(BuildSegmentRates) 原各有一份相同的GetFixingDate+TryGetFixing+throw逻辑(~8行/处,3处共24行)。 提取为私有 ResolveFloatRate(position, date, fallback): - 无浮动标的返回fallback; 取到非零fixing返回fixing; 取不到抛异常 - EOD: isResetDay ? ResolveFloatRate(...) : floateRate (1行替代12行) - BuildSegmentRates: 循环内直接调用(1行替代8行) 净减~15行, FR007定盘逻辑收口到一处 SwapModule零回归(7基线/510通过)
This commit is contained in:
@@ -1326,6 +1326,19 @@ namespace YLErp.Modules.SwapModule
|
||||
return interest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按 interest_rule 取 FR007 定盘价。无浮动标的时返回 fallback;取不到抛异常。
|
||||
/// EOD 单日取率 + BuildSegmentRates 多日取率共用此方法,FR007 定盘逻辑收口到一处。
|
||||
/// </summary>
|
||||
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日}的价格");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按重置周期切分利率段,每段记录 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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user