refactor(margin): 抽取 ResolveMarginOrginPv 保证金维度重映射方法

把 InitSwapDealInterest 里 8 行 inline 的 orginPv 重映射逻辑抽成独立方法
ResolveMarginOrginPv(position, preEodPosition, fallback)。

保证金腿被迫走融资腿差分公式(dynomicPrincipal = TdPrincipal + posi - orginPv),
但 orginPv 对融资腿是'交易名义本金',对保证金腿须对齐到'保证金余额',
否则维度不匹配算出巨负值。提取后 InitSwapDealInterest 更干净,
且新方法待迁入 Margin 模块。

判断从 InterestModeEnum==5||6 改为 MarginModes.Contains(统一口径)。
纯提取, 行为零变化。
验证: 编译0错误, 全量489测试7失败(基线一致)。
This commit is contained in:
hjhan
2026-08-11 10:23:22 +08:00
parent e73272042a
commit ae4af111f3
+22 -15
View File
@@ -1150,6 +1150,25 @@ namespace YLErp.Modules.SwapModule
return InitSwapDealInterest(td, valueDate, endDate, rate, position, add, swap, posiPrincipal, closePrincipal, closePercent, annualDays, eventType, preEod, false, orginPv, calcFirst, calcLast, consumedInterest);
}
/// <summary>
/// 保证金腿的 orginPv 维度重映射。
///
/// 保证金腿被迫走融资腿的差分公式(dynomicPrincipal = TdInterestPrincipal + posiPrincipal - orginPv)
/// 但 orginPv 对融资腿是"交易名义本金(千万~亿级)",对保证金腿必须是"保证金本金"——
/// 否则维度不匹配会算出巨负值。本方法把保证金场景的 orginPv 对齐到"上一日保证金本金"。
///
/// 待迁入 Margin 模块:保证金独立计息入口建好后,此方法移入 MarginAccount/MarginService。
/// </summary>
private decimal ResolveMarginOrginPv(swap_position position, eod_swap_position preEodPosition, decimal fallback)
{
var previousBalance = preEodPosition.InterestPrincipalFix != 0m
? preEodPosition.InterestPrincipalFix
: preEodPosition.TdInterestPrincipal;
return preEodPosition.id != 0 && previousBalance != 0m
? previousBalance
: fallback;
}
/// <summary>
/// 初始化利息腿信息
/// </summary>
@@ -1203,22 +1222,10 @@ namespace YLErp.Modules.SwapModule
interest.ClientId = td.ClientId;
interest.UnwindDate = endDate;
// 根因修复:预付金(保证金)腿的计息基数维度应为"保证金本金"自身,而非整笔交易的名义本金(orginPv)。
// 否则公式 dynomicPrincipal = TdInterestPrincipal + posiPrincipal - orginPv
// 会把交易名义本金(千万~亿级)当减项扣掉,使"应返还本金"(InterestPrincipal)与计息基数变成巨负值。
// 此处将预付金腿的 orginPv 对齐为上一日保证金本金;无历史归档时才取当前本金。
// 差分公式必须使用同一时点口径:上一日本金 + 当前本金 - 上一本金 = 当前本金。
// 若已有部分平仓后仍取当前本金,会把上一日本金原样保留,导致当日继续按平仓前本金计息。
// 仅作用于初始预付金(5)/追加预付金(6);其它计息模式(含债券本金腿 标的期初全价=9)仍用交易名义本金,不受影响。
if (position.InterestMode == (int)InterestModeEnum.
|| position.InterestMode == (int)InterestModeEnum.)
// 保证金腿的 orginPv 对齐到保证金本金维度,避免差分公式维度不匹配算出巨负值
if (MarginModes.Contains(position.InterestMode))
{
var previousPrincipal = preEodPosition.InterestPrincipalFix != 0m
? preEodPosition.InterestPrincipalFix
: preEodPosition.TdInterestPrincipal;
orginPv = preEodPosition.id != 0 && previousPrincipal != 0m
? previousPrincipal
: position.InterestPrincipalFix;
orginPv = ResolveMarginOrginPv(position, preEodPosition, position.InterestPrincipalFix);
}
if (swap)