namespace YLErp.Modules.SwapModule;
///
/// GetInterests 参数对象(2026-08 参数显式化)。
///
/// 动机:原 GetInterests 20 个位置参数中,名义本金簇(posiNotionalValue/closePosiNotionalValue/closePercent)
/// 在【盘中平仓】与【EOD 平仓后收盘】两类场景下语义相反(详见 GetInterests "根因位置"注释与
/// GetInterestsEntrySemanticsTest 的口径留档),位置参数无法表达该约束。
///
/// 用法:只能经两个场景工厂构造——工厂形参名即该场景语义(平仓前剩余 / 平仓后剩余 / 实际平掉额),
/// 物理上防止两套语义混传。needPrice/grossPrice 为原方法死参数(体内零消费),本对象不承载。
///
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; }
public decimal PosiLongNotionalValue { get; }
public decimal PosiShortNotionalValue { 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 posiLongNotionalValue, decimal posiShortNotionalValue,
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; PosiLongNotionalValue = posiLongNotionalValue;
PosiShortNotionalValue = posiShortNotionalValue; 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 preCloseLongNotional, decimal preCloseShortNotional,
decimal closedNotional, decimal closePercentRemaining,
int eventType, bool tdClose, decimal orginPv,
bool add, bool newCalcLast, List closeList)
=> new(td, tradeExtend, valueDate, unwindDate, eodPositions, positions,
preCloseNotional, preCloseLongNotional, preCloseShortNotional,
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 remainingLongNotional, decimal remainingShortNotional,
decimal closedNotional,
int eventType, bool tdClose, decimal orginPv,
bool add, bool newCalcLast)
=> new(td, tradeExtend, valueDate, unwindDate, eodPositions, positions,
remainingNotionalAfterClose, remainingLongNotional, remainingShortNotional,
closedNotional, 1m, // 恒1:本次事件全额结息(非 closeNational / 期初比例)
eventType, tdClose, orginPv, add, newCalcLast, closeList: null);
}