refactor(swap-eod): L1 类内去重——CopyInterestLegFields/FinalizeInterestEodRoll 收口四 Save* 重复段(行为保真)
- 腿字段拷贝 3 处×14 行 → 入参化 helper(FloatRate 来源随场景传入,勿统一) - 滚存收尾 4 处 → FinalizeInterestEodRoll(方向源参数化:三处 position、Copy 一处 eodPayPosition,勿统一;Persist 与日志留调用点保持原序) - 差异保真:WithClose 不设 InterestFeePending;勿缩放注释保留升级 - 安全网:InterestEodTailSnapshotTest 三格尾部快照(AutoSettle/AutoSettleWithClose/CloseOnly,钉值特征化)+ golden 两格 + DI_EXCEL 家族 - 验证:快照 3/3 逐字段一致;全量 SwapModule 576/566/10/0 与去重前基线完全相同 - 注:本提交为工作区被还原后按原编辑重放,验证结果与首次执行一致
This commit is contained in:
@@ -980,6 +980,46 @@ namespace YLErp.Modules.SwapModule
|
||||
trans?.Dispose();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 利息腿字段拷贝(SaveEodInterestPosition / SaveAutoEodInterestPosition / SaveAutoEodWithCloseInterestPosition 共用)。
|
||||
/// FloatRate 来源随场景不同(手工互换=当日流水;自动互换/平仓=计息结果),由调用方算好传入,勿在本方法内统一。
|
||||
/// 场景差异字段(PosiStatus / InterestFeePending / TdInterestPrincipal / TdInterestRate)留在各调用点。
|
||||
/// </summary>
|
||||
private static void CopyInterestLegFields(eod_swap_position newEodPayPosition, swap_position position, decimal floatRate)
|
||||
{
|
||||
newEodPayPosition.InterestDirection = position.InterestDirection;
|
||||
newEodPayPosition.InterestMode = position.InterestMode;
|
||||
newEodPayPosition.InterestPrincipalFix = position.InterestPrincipalFix;
|
||||
newEodPayPosition.InterestRateDefault = position.InterestRateDefault;
|
||||
newEodPayPosition.InterestSwapInterval = position.InterestSwapInterval;
|
||||
newEodPayPosition.IsAnnualized = position.IsAnnualized;
|
||||
newEodPayPosition.HappenDate = position.HappenDate;
|
||||
newEodPayPosition.Currency = position.Currency;
|
||||
newEodPayPosition.InterestType = position.InterestType;
|
||||
newEodPayPosition.interest_rest_days = position.interest_rest_days;
|
||||
newEodPayPosition.interest_rule = position.interest_rule;
|
||||
newEodPayPosition.FloatRate = floatRate;
|
||||
newEodPayPosition.FloatRateUnderlyingCode = position.FloatRateUnderlyingCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 利息腿日终滚存收尾(四个 Save* 共用):RollRealized 滚累计已实现 → SetFixedLegRealizedPnl → 汇率 → TdCurrency。
|
||||
/// RealizedInterest 只增不回滚:上日累计已实现 + 当日结息按方向后的金额。
|
||||
/// interestDirection 是 RateType 的方向来源——三个方法取 position.InterestDirection,
|
||||
/// SaveEodInterestPositionCopy 取 eodPayPosition.InterestDirection(现状差异,勿统一)。
|
||||
/// PersistEodSwapPosition 与各自日志留在调用点(持久化边界 + 日志顺序各不相同)。
|
||||
/// </summary>
|
||||
private void FinalizeInterestEodRoll(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, int ratio, trade td, DateTime valueDate, int interestDirection)
|
||||
{
|
||||
var rolled = InterestIncomeCalc.RollRealized(eodPayPosition.RealizedInterest, eodPayPosition.RealizedInterestFee, newEodPayPosition.TdCloseInterest, newEodPayPosition.TdCloseInterestFee, ratio);
|
||||
newEodPayPosition.RealizedInterest = rolled.Interest;
|
||||
newEodPayPosition.RealizedInterestFee = rolled.Fee;
|
||||
SetFixedLegRealizedPnl(newEodPayPosition);
|
||||
var currencyRate = GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate, true,
|
||||
DirectionRatio.RateType(interestDirection));
|
||||
newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产生互换用
|
||||
/// </summary>
|
||||
@@ -1023,20 +1063,8 @@ namespace YLErp.Modules.SwapModule
|
||||
UpdateDbOption(newEodPayPosition);
|
||||
newEodPayPosition.PosiStatus = 0;
|
||||
newEodPayPosition.Invalid = false;
|
||||
//持仓内容-利息腿
|
||||
newEodPayPosition.InterestDirection = position.InterestDirection;
|
||||
newEodPayPosition.InterestMode = position.InterestMode;
|
||||
newEodPayPosition.InterestPrincipalFix = position.InterestPrincipalFix;
|
||||
newEodPayPosition.InterestRateDefault = position.InterestRateDefault;
|
||||
newEodPayPosition.InterestSwapInterval = position.InterestSwapInterval;
|
||||
newEodPayPosition.IsAnnualized = position.IsAnnualized;
|
||||
newEodPayPosition.HappenDate = position.HappenDate;
|
||||
newEodPayPosition.Currency = position.Currency;
|
||||
newEodPayPosition.InterestType = position.InterestType;
|
||||
newEodPayPosition.interest_rest_days = position.interest_rest_days;
|
||||
newEodPayPosition.interest_rule = position.interest_rule;
|
||||
newEodPayPosition.FloatRate = flowEvents.FirstOrDefault()?.FloatRate ?? 0;
|
||||
newEodPayPosition.FloatRateUnderlyingCode = position.FloatRateUnderlyingCode;
|
||||
//持仓内容-利息腿(FloatRate 取当日互换/平仓流水)
|
||||
CopyInterestLegFields(newEodPayPosition, position, flowEvents.FirstOrDefault()?.FloatRate ?? 0);
|
||||
newEodPayPosition.InterestFeePending = 0;
|
||||
//利息端估值用信息
|
||||
newEodPayPosition.TdInterestPrincipal = flowEvents.FirstOrDefault()?.InterestPrincipal ?? 0;
|
||||
@@ -1074,14 +1102,8 @@ namespace YLErp.Modules.SwapModule
|
||||
//持仓价值
|
||||
newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, (int)ratio);
|
||||
|
||||
//累计已实现
|
||||
var rolled = InterestIncomeCalc.RollRealized(eodPayPosition.RealizedInterest, eodPayPosition.RealizedInterestFee, newEodPayPosition.TdCloseInterest, newEodPayPosition.TdCloseInterestFee, ratio);
|
||||
newEodPayPosition.RealizedInterest = rolled.Interest;
|
||||
newEodPayPosition.RealizedInterestFee = rolled.Fee;
|
||||
SetFixedLegRealizedPnl(newEodPayPosition);
|
||||
var currencyRate = GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate, true,
|
||||
DirectionRatio.RateType(position.InterestDirection));
|
||||
newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate);
|
||||
//累计已实现(滚存收尾见 FinalizeInterestEodRoll)
|
||||
FinalizeInterestEodRoll(eodPayPosition, newEodPayPosition, ratio, td, valueDate, position.InterestDirection);
|
||||
PersistEodSwapPosition(newEodPayPosition);
|
||||
}
|
||||
/// <summary>
|
||||
@@ -1179,20 +1201,8 @@ namespace YLErp.Modules.SwapModule
|
||||
newEodPayPosition.PositionId = position.id;
|
||||
UpdateDbOption(newEodPayPosition);
|
||||
newEodPayPosition.Invalid = false;
|
||||
//持仓内容-利息腿
|
||||
newEodPayPosition.InterestDirection = position.InterestDirection;
|
||||
newEodPayPosition.InterestMode = position.InterestMode;
|
||||
newEodPayPosition.InterestPrincipalFix = position.InterestPrincipalFix;
|
||||
newEodPayPosition.InterestRateDefault = position.InterestRateDefault;
|
||||
newEodPayPosition.InterestSwapInterval = position.InterestSwapInterval;
|
||||
newEodPayPosition.IsAnnualized = position.IsAnnualized;
|
||||
newEodPayPosition.HappenDate = position.HappenDate;
|
||||
newEodPayPosition.Currency = position.Currency;
|
||||
newEodPayPosition.InterestType = position.InterestType;
|
||||
newEodPayPosition.interest_rest_days = position.interest_rest_days;
|
||||
newEodPayPosition.interest_rule = position.interest_rule;
|
||||
newEodPayPosition.FloatRate = interests.Count > 0 ? interests.First().FloatRate ?? 0 : 0;
|
||||
newEodPayPosition.FloatRateUnderlyingCode = position.FloatRateUnderlyingCode;
|
||||
//持仓内容-利息腿(FloatRate 取计息结果)
|
||||
CopyInterestLegFields(newEodPayPosition, position, interests.Count > 0 ? interests.First().FloatRate ?? 0 : 0);
|
||||
newEodPayPosition.InterestFeePending = 0;
|
||||
//利息端估值用信息
|
||||
newEodPayPosition.TdInterestPrincipal = interestModes.Contains(position.InterestMode) ? eodPayPosition.InterestPrincipalFix : posiNotionalValue;
|
||||
@@ -1216,14 +1226,8 @@ namespace YLErp.Modules.SwapModule
|
||||
//持仓价值
|
||||
newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, (int)ratio);
|
||||
|
||||
//累计已实现
|
||||
var rolled = InterestIncomeCalc.RollRealized(eodPayPosition.RealizedInterest, eodPayPosition.RealizedInterestFee, newEodPayPosition.TdCloseInterest, newEodPayPosition.TdCloseInterestFee, ratio);
|
||||
newEodPayPosition.RealizedInterest = rolled.Interest;
|
||||
newEodPayPosition.RealizedInterestFee = rolled.Fee;
|
||||
SetFixedLegRealizedPnl(newEodPayPosition);
|
||||
var currencyRate = GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate, true,
|
||||
DirectionRatio.RateType(position.InterestDirection));
|
||||
newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate);
|
||||
//累计已实现(滚存收尾见 FinalizeInterestEodRoll)
|
||||
FinalizeInterestEodRoll(eodPayPosition, newEodPayPosition, ratio, td, valueDate, position.InterestDirection);
|
||||
PersistEodSwapPosition(newEodPayPosition);
|
||||
Log.Info($"the last newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
return interests;
|
||||
@@ -1354,22 +1358,9 @@ namespace YLErp.Modules.SwapModule
|
||||
newEodPayPosition.PositionId = position.id;
|
||||
UpdateDbOption(newEodPayPosition);
|
||||
newEodPayPosition.Invalid = false;
|
||||
//持仓内容-利息腿
|
||||
newEodPayPosition.InterestDirection = position.InterestDirection;
|
||||
newEodPayPosition.InterestMode = position.InterestMode;
|
||||
// ResolveInterestLegPositions 已提供平仓后的实时剩余本金,日终不再重复扣减。
|
||||
newEodPayPosition.InterestPrincipalFix = position.InterestPrincipalFix;
|
||||
// newEodPayPosition.InterestPrincipalFix *= (1 - closePercent);
|
||||
newEodPayPosition.InterestRateDefault = position.InterestRateDefault;
|
||||
newEodPayPosition.InterestSwapInterval = position.InterestSwapInterval;
|
||||
newEodPayPosition.IsAnnualized = position.IsAnnualized;
|
||||
newEodPayPosition.HappenDate = position.HappenDate;
|
||||
newEodPayPosition.Currency = position.Currency;
|
||||
newEodPayPosition.InterestType = position.InterestType;
|
||||
newEodPayPosition.FloatRate = interests.Count > 0 ? interests.First().FloatRate ?? 0 : 0;
|
||||
newEodPayPosition.FloatRateUnderlyingCode = position.FloatRateUnderlyingCode;
|
||||
newEodPayPosition.interest_rest_days = position.interest_rest_days;
|
||||
newEodPayPosition.interest_rule = position.interest_rule;
|
||||
//持仓内容-利息腿(FloatRate 取计息结果)。InterestPrincipalFix 保持腿现值:
|
||||
// ResolveInterestLegPositions 已提供平仓后的实时剩余本金,日终不再重复扣减(勿恢复 *(1-closePercent))。
|
||||
CopyInterestLegFields(newEodPayPosition, position, interests.Count > 0 ? interests.First().FloatRate ?? 0 : 0);
|
||||
//利息端估值用信息
|
||||
// TdInterestPrincipal 是“下一日继续计息的收盘后本金”,不是原始合同规模,也不是本次平仓本金。
|
||||
// 模式9单利直接取剩余名义本金;复利还要保留重置时已经并入本金的待实现利息。
|
||||
@@ -1491,16 +1482,8 @@ namespace YLErp.Modules.SwapModule
|
||||
$",TdCloseInterest is {newEodPayPosition.TdCloseInterest}");
|
||||
Log.Info($"InterestFeeSum is {eodPayPosition.InterestFeeSum},TdInterestFee is {newEodPayPosition.TdInterestFee}" +
|
||||
$",TdCloseInterestFee is {newEodPayPosition.TdCloseInterestFee}");
|
||||
//累计已实现
|
||||
// RealizedInterest 只增不回滚:上日累计已实现 + 当日结息按方向后的金额。
|
||||
// 收取腿的 -37119.14 会把累计已实现更新为 -37119.14;后续普通 EOD 保持该值。
|
||||
var rolled = InterestIncomeCalc.RollRealized(eodPayPosition.RealizedInterest, eodPayPosition.RealizedInterestFee, newEodPayPosition.TdCloseInterest, newEodPayPosition.TdCloseInterestFee, ratio);
|
||||
newEodPayPosition.RealizedInterest = rolled.Interest;
|
||||
newEodPayPosition.RealizedInterestFee = rolled.Fee;
|
||||
SetFixedLegRealizedPnl(newEodPayPosition);
|
||||
var currencyRate = GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate, true,
|
||||
DirectionRatio.RateType(position.InterestDirection));
|
||||
newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate);
|
||||
//累计已实现(滚存语义见 FinalizeInterestEodRoll:只增不回滚)
|
||||
FinalizeInterestEodRoll(eodPayPosition, newEodPayPosition, ratio, td, valueDate, position.InterestDirection);
|
||||
Log.Info($"即将插入数据库的 newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
PersistEodSwapPosition(newEodPayPosition);
|
||||
return interests;
|
||||
@@ -1614,14 +1597,8 @@ namespace YLErp.Modules.SwapModule
|
||||
//持仓价值
|
||||
newEodPayPosition.SwapPositionValue = PositionValueCalc.Calc(newEodPayPosition.InterestProfitSum, newEodPayPosition.PosiProfitSum, (int)ratio);
|
||||
|
||||
//累计已实现
|
||||
var rolled = InterestIncomeCalc.RollRealized(eodPayPosition.RealizedInterest, eodPayPosition.RealizedInterestFee, newEodPayPosition.TdCloseInterest, newEodPayPosition.TdCloseInterestFee, ratio);
|
||||
newEodPayPosition.RealizedInterest = rolled.Interest;
|
||||
newEodPayPosition.RealizedInterestFee = rolled.Fee;
|
||||
SetFixedLegRealizedPnl(newEodPayPosition);
|
||||
var currencyRate = GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate, true,
|
||||
DirectionRatio.RateType(eodPayPosition.InterestDirection));
|
||||
newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate);
|
||||
//累计已实现(滚存收尾见 FinalizeInterestEodRoll;方向源=eodPayPosition,与其他三方法不同,勿统一)
|
||||
FinalizeInterestEodRoll(eodPayPosition, newEodPayPosition, ratio, td, valueDate, eodPayPosition.InterestDirection);
|
||||
Log.Info($"the last newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
PersistEodSwapPosition(newEodPayPosition);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user