refactor: 删除 CalcNotionalByMode, 保证金/融资腿计息基数内联到调用点
CalcNotionalByMode 已完成历史使命: - 融资腿(1/2/9)迁入 FundingLegStrategyFactory - 保证金(5/6)迁入 MarginModes.Contains 分支 - 死代码(3/4/7/8)已删 调用点(GetInterests:843)现在内联两条路径: - 保证金: closePrincipal = Fix × closePercent (用 MarginModes.Contains 判断) - 融资腿: FundingLegStrategyFactory.Get(mode).CalcNotional(...) 删除: - CalcNotionalByMode 方法(含注释) - 2个用反射调私有方法的诊断测试(验证的逻辑已被FundingLegStrategyTest覆盖) 验证: 编译0错误, 全量509测试7失败(基线一致)。
This commit is contained in:
@@ -66,33 +66,5 @@ namespace YLErp.Modules.SwapModule
|
||||
TradeDate = D0, StartDate = D0, ExerciseDate = D1, TradeStatus = "确认成交", ValidState = "Valid",
|
||||
StockEqvNotional = (double)RealLong, Notional = (double)RealLong, trade_extend = extend };
|
||||
}
|
||||
|
||||
/// <summary>用反射调用 private CalcNotionalByMode,直接证明各 mode 的 closePrincipal 是否依赖 posiLong/posiShort。</summary>
|
||||
private (decimal close, decimal posi, decimal pct) CallCalcNotionalByMode(swap_position position, decimal closePct, decimal posiNotional, decimal posiLong, decimal posiShort)
|
||||
{
|
||||
var m = typeof(SwapDealService).GetMethod("CalcNotionalByMode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
return ((decimal, decimal, decimal))m.Invoke(_svc, new object[] { position, closePct, posiNotional, posiLong, posiShort });
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void 诊断_mode9_标的期初全价_closePrincipal_不依赖posiLong_而用posiNotional()
|
||||
{
|
||||
// mode 9 分支:closePrincipal = posiNotional * closePercent
|
||||
var baseP = OrigBasePrice();
|
||||
var (close, posi, _) = CallCalcNotionalByMode(baseP, ClosePct, RealLong * ClosePct, OrigLong, 0m);
|
||||
Console.WriteLine($"[mode9] posiNotional={RealLong * ClosePct} posiLong(orig)={OrigLong} → closePrincipal={close}");
|
||||
Assert.AreEqual(RealLong * ClosePct * ClosePct, close, "mode9 应 = posiNotional(=real剩余*closePct) * closePct,与 posiLong(orig 100M) 无关");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void 诊断_mode5_预付金_closePrincipal_用自身Fix_不依赖posiLong()
|
||||
{
|
||||
// mode 5 分支:closePrincipal = position.InterestPrincipalFix * closePercent(用 Clone 后的 real Fix)
|
||||
var prepay = RealPrepay(); // Fix = RealFix(66,813.12)
|
||||
var (close, posi, _) = CallCalcNotionalByMode(prepay, ClosePct, RealLong * ClosePct, OrigLong, 0m);
|
||||
Console.WriteLine($"[mode5] Fix(cloned real)={RealFix} posiLong(orig)={OrigLong} → closePrincipal={close}");
|
||||
Assert.AreEqual(RealFix * ClosePct, close, "mode5 应 = 实时腿剩余本金(real Fix) * closePct,与 posiLong(orig 100M) 无关");
|
||||
Assert.AreNotEqual(OrigFix * ClosePct, close, "务必不是期初 99,000 * closePct(证明后端修复生效)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -840,7 +840,26 @@ namespace YLErp.Modules.SwapModule
|
||||
bool swap = InitInterestDate(unwindDate, preDealDate, td, tdClose, out DateTime startDate, out DateTime endDate);
|
||||
|
||||
// 计算名义本金
|
||||
var (closePrincipal, posiPrincipal, newClosePercent) = CalcNotionalByMode(position, closePrecent, posiNotionalValue, posiLongNotionalValue, posiShortNotionalValue);
|
||||
decimal closePrincipal;
|
||||
decimal posiPrincipal;
|
||||
decimal newClosePercent = closePrecent;
|
||||
var mode = (InterestModeEnum)position.InterestMode;
|
||||
|
||||
if (MarginModes.Contains(position.InterestMode))
|
||||
{
|
||||
// 保证金腿: 计息基数 = InterestPrincipalFix(保证金余额)
|
||||
closePrincipal = position.InterestPrincipalFix * closePrecent;
|
||||
posiPrincipal = position.InterestPrincipalFix;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 融资腿(1/2/9): 走策略工厂
|
||||
var r = FundingLegStrategyFactory.Get(mode)
|
||||
.CalcNotional(position.InterestPrincipalFix, posiNotionalValue, posiLongNotionalValue, posiShortNotionalValue, closePrecent);
|
||||
closePrincipal = r.ClosePrincipal;
|
||||
posiPrincipal = r.PosiPrincipal;
|
||||
newClosePercent = r.ClosePercent;
|
||||
}
|
||||
if ((InterestModeEnum)position.InterestMode == InterestModeEnum.合约名义本金规模
|
||||
|| (InterestModeEnum)position.InterestMode == InterestModeEnum.标的期初全价
|
||||
&& posiNotionalValue == 0m)
|
||||
@@ -904,51 +923,9 @@ namespace YLErp.Modules.SwapModule
|
||||
return interests;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据计息模式计算名义本金。
|
||||
///
|
||||
/// 现状(过渡期):
|
||||
/// - 融资腿(mode 1/2/9)已委托 FundingLegStrategyFactory,走新策略体系。
|
||||
/// - 保证金(mode 5/6)暂保留——待 Margin 独立计息入口建成后迁出。
|
||||
/// - 多空存续(mode 7/8)界面已禁用,保留 case 仅为防御性兜底。
|
||||
/// - 死代码(mode 3/4)走 default。
|
||||
///
|
||||
/// 待保证金(mode 5/6)迁入 Margin 上下文后,本方法可整体删除,
|
||||
/// 调用点直接走 FundingLegStrategyFactory.Get(mode)。
|
||||
/// </summary>
|
||||
private (decimal close, decimal posi, decimal closePct) CalcNotionalByMode(swap_position position, decimal closePercent, decimal posiNotional, decimal posiLong, decimal posiShort)
|
||||
{
|
||||
var mode = (InterestModeEnum)position.InterestMode;
|
||||
|
||||
// 融资腿(1/2/9)走策略工厂
|
||||
if (mode == InterestModeEnum.固定值
|
||||
|| mode == InterestModeEnum.合约名义本金规模
|
||||
|| mode == InterestModeEnum.标的期初全价)
|
||||
{
|
||||
var r = FundingLegStrategyFactory.Get(mode)
|
||||
.CalcNotional(position.InterestPrincipalFix, posiNotional, posiLong, posiShort, closePercent);
|
||||
return (r.ClosePrincipal, r.PosiPrincipal, r.ClosePercent);
|
||||
}
|
||||
|
||||
// 以下 mode 尚未迁入新架构,保留原逻辑
|
||||
decimal closePrincipal = posiNotional;
|
||||
decimal posiPrincipal = posiNotional;
|
||||
decimal newClosePercent = closePercent;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case InterestModeEnum.追加预付金:
|
||||
case InterestModeEnum.初始预付金:
|
||||
closePrincipal = position.InterestPrincipalFix * closePercent;
|
||||
posiPrincipal = position.InterestPrincipalFix;
|
||||
break;
|
||||
}
|
||||
return (closePrincipal, posiPrincipal, newClosePercent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 平仓比例口径转换(解决"显示占期初 / 计算占剩余"双语义问题)。
|
||||
/// 前端与事件列表展示用"占期初(original)"语义(A);后端 CalcNotionalByMode / 费用递减 /
|
||||
/// 前端与事件列表展示用"占期初(original)"语义(A);后端计息基数计算 / 费用递减 /
|
||||
/// 全平判定均按"占剩余(remaining)"语义(B)消费。
|
||||
/// A → B:B = A × 期初名义本金(NotionalValue) / 剩余名义本金(PosiNotionalValue),并 cap 到 1。
|
||||
/// B → A:A = B × 剩余名义本金 / 期初名义本金。
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "http://localhost:49462",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "dev"
|
||||
"ASPNETCORE_ENVIRONMENT": "local"
|
||||
},
|
||||
"applicationUrl": "http://localhost:49462"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user