namespace YLErp.Modules.SwapModule;
///
/// GetInterests 参数对象(2026-08 参数显式化)。
///
/// 动机:原 GetInterests 20 个位置参数中,名义本金簇(posiNotionalValue/closePosiNotionalValue/closePercent)
/// 在【盘中平仓】与【EOD 平仓后收盘】两类场景下语义相反(详见 GetInterests "根因位置"注释与
/// GetInterestsEntrySemanticsTest 的口径留档),位置参数无法表达该约束。
///
/// 用法:只能经两个场景工厂构造——工厂形参名即该场景语义(平仓前剩余 / 平仓后剩余 / 实际平掉额),
/// 物理上防止两套语义混传。needPrice/grossPrice(原方法死参数)与 posiLong/posiShortNotionalValue
/// (多空组合子系统删除后计息链零消费的管道死参数)均不承载。
///
public sealed class InterestCalcRequest
{
public trade Td { get; }
public trade_extend TradeExtend { get; }
public DateTime ValueDate { get; }
public DateTime UnwindDate { get; }
public List EodPositions { get; }
public List Positions { get; }
/// 当日适用名义本金。语义随场景:盘中=平仓【前】剩余;EOD平仓后收盘=平仓【后】剩余;EOD增量=当前剩余。
public decimal PosiNotionalValue { get; }
/// 本次实际平掉本金(两场景恒同义)。mode2 无条件覆盖 / mode9 全平兜底的输入。
public decimal ClosePosiNotionalValue { get; }
/// 平仓比例。语义随场景:盘中=实际比例(B 占剩余);EOD平仓后收盘=恒1(全额结息)。
public decimal ClosePercent { get; }
public int EventType { get; }
public bool TdClose { get; }
public decimal OrginPv { get; }
public bool Add { get; }
public bool NewCalcLast { get; }
public List CloseList { get; }
private InterestCalcRequest(
trade td, trade_extend tradeExtend, DateTime valueDate, DateTime unwindDate,
List eodPositions, List positions,
decimal posiNotionalValue,
decimal closePosiNotionalValue, decimal closePercent,
int eventType, bool tdClose, decimal orginPv,
bool add, bool newCalcLast, List closeList)
{
Td = td; TradeExtend = tradeExtend; ValueDate = valueDate; UnwindDate = unwindDate;
EodPositions = eodPositions; Positions = positions;
PosiNotionalValue = posiNotionalValue; ClosePosiNotionalValue = closePosiNotionalValue;
ClosePercent = closePercent; EventType = eventType; TdClose = tdClose; OrginPv = orginPv;
Add = add; NewCalcLast = newCalcLast; CloseList = closeList;
}
///
/// 【盘中平仓/互换结息】场景(→ GetIntradayUnwindInterests,settment:false 盘中重放)。
///
/// 平仓【前】实时剩余本金(原 GetUnwindInterests.stockEqvNotional)。
/// 本次实际平掉本金(= preCloseNotional × closePercentRemaining)。
/// 平仓比例,B 语义【占剩余】(前端传 A 占期初须先经 ToRemainingClosePercent 转换)。
public static InterestCalcRequest IntradayUnwind(
trade td, trade_extend tradeExtend, DateTime valueDate, DateTime unwindDate,
List eodPositions, List positions,
decimal preCloseNotional, decimal closedNotional, decimal closePercentRemaining,
int eventType, bool tdClose, decimal orginPv,
bool add, bool newCalcLast, List closeList)
=> new(td, tradeExtend, valueDate, unwindDate, eodPositions, positions,
preCloseNotional, closedNotional, closePercentRemaining,
eventType, tdClose, orginPv, add, newCalcLast, closeList);
///
/// 【EOD 当日有平仓后的收盘结息】场景(→ CalcEodPostCloseSettleInterests,settment:false 全额结息)。
/// 该场景触发 GetInterests 内 mode2 无条件覆盖 / mode9 全平兜底(见其"根因位置"注释,勿删)。
///
/// 平仓【后】剩余本金(GetInterests.posiNotionalValue 形参位)。
/// 本次实际平掉本金。
public static InterestCalcRequest EodPostCloseSettle(
trade td, trade_extend tradeExtend, DateTime valueDate, DateTime unwindDate,
List eodPositions, List positions,
decimal remainingNotionalAfterClose, decimal closedNotional,
int eventType, bool tdClose, decimal orginPv,
bool add, bool newCalcLast)
=> new(td, tradeExtend, valueDate, unwindDate, eodPositions, positions,
remainingNotionalAfterClose, closedNotional, 1m, // 恒1:本次事件全额结息(非 closeNational / 期初比例)
eventType, tdClose, orginPv, add, newCalcLast, closeList: null);
}