新增 UnwindData.IsPenaltyInterest(bool);InterestCalcRequest 加 IsPenaltyInterest 字段+私有ctor参数+IntradayUnwind 工厂可选参(default false);GetUnwindInterests 加 isPenaltyInterest 可选参并透传 IntradayUnwind。零行为变化,现有调用方经默认值不受影响,Penalty 套件 11/11 通过。
92 lines
5.4 KiB
C#
92 lines
5.4 KiB
C#
namespace YLErp.Modules.SwapModule;
|
||
|
||
/// <summary>
|
||
/// GetInterests 参数对象(2026-08 参数显式化)。
|
||
///
|
||
/// 动机:原 GetInterests 20 个位置参数中,名义本金簇(posiNotionalValue/closePosiNotionalValue/closePercent)
|
||
/// 在【盘中平仓】与【EOD 平仓后收盘】两类场景下语义相反(详见 GetInterests "根因位置"注释与
|
||
/// GetInterestsEntrySemanticsTest 的口径留档),位置参数无法表达该约束。
|
||
///
|
||
/// 用法:只能经两个场景工厂构造——工厂形参名即该场景语义(平仓前剩余 / 平仓后剩余 / 实际平掉额),
|
||
/// 物理上防止两套语义混传。needPrice/grossPrice(原方法死参数)与 posiLong/posiShortNotionalValue
|
||
/// (多空组合子系统删除后计息链零消费的管道死参数)均不承载。
|
||
/// </summary>
|
||
public sealed class InterestCalcRequest
|
||
{
|
||
public trade Td { get; }
|
||
public trade_extend TradeExtend { get; }
|
||
public DateTime ValueDate { get; }
|
||
public DateTime UnwindDate { get; }
|
||
public List<eod_swap_position> EodPositions { get; }
|
||
public List<swap_position> Positions { get; }
|
||
|
||
/// <summary>当日适用名义本金。语义随场景:盘中=平仓【前】剩余;EOD平仓后收盘=平仓【后】剩余;EOD增量=当前剩余。</summary>
|
||
public decimal PosiNotionalValue { get; }
|
||
|
||
/// <summary>本次实际平掉本金(两场景恒同义)。mode2 无条件覆盖 / mode9 全平兜底的输入。</summary>
|
||
public decimal ClosePosiNotionalValue { get; }
|
||
|
||
/// <summary>平仓比例。语义随场景:盘中=实际比例(B 占剩余);EOD平仓后收盘=恒1(全额结息)。</summary>
|
||
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<swap_flow_event> CloseList { get; }
|
||
|
||
/// <summary>是否计罚息(EQD-6977):利息端按持有至到期计息。由平仓页下拉经 UnwindData 透传;默认 false。</summary>
|
||
public bool IsPenaltyInterest { get; }
|
||
|
||
private InterestCalcRequest(
|
||
trade td, trade_extend tradeExtend, DateTime valueDate, DateTime unwindDate,
|
||
List<eod_swap_position> eodPositions, List<swap_position> positions,
|
||
decimal posiNotionalValue,
|
||
decimal closePosiNotionalValue, decimal closePercent,
|
||
int eventType, bool tdClose, decimal orginPv,
|
||
bool add, bool newCalcLast, List<swap_flow_event> closeList,
|
||
bool isPenaltyInterest = false)
|
||
{
|
||
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;
|
||
IsPenaltyInterest = isPenaltyInterest;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 【盘中平仓/互换结息】场景(→ GetIntradayUnwindInterests,settment:false 盘中重放)。
|
||
/// </summary>
|
||
/// <param name="preCloseNotional">平仓【前】实时剩余本金(原 GetUnwindInterests.stockEqvNotional)。</param>
|
||
/// <param name="closedNotional">本次实际平掉本金(= preCloseNotional × closePercentRemaining)。</param>
|
||
/// <param name="closePercentRemaining">平仓比例,B 语义【占剩余】(前端传 A 占期初须先经 ToRemainingClosePercent 转换)。</param>
|
||
public static InterestCalcRequest IntradayUnwind(
|
||
trade td, trade_extend tradeExtend, DateTime valueDate, DateTime unwindDate,
|
||
List<eod_swap_position> eodPositions, List<swap_position> positions,
|
||
decimal preCloseNotional, decimal closedNotional, decimal closePercentRemaining,
|
||
int eventType, bool tdClose, decimal orginPv,
|
||
bool add, bool newCalcLast, List<swap_flow_event> closeList,
|
||
bool isPenaltyInterest = false)
|
||
=> new(td, tradeExtend, valueDate, unwindDate, eodPositions, positions,
|
||
preCloseNotional, closedNotional, closePercentRemaining,
|
||
eventType, tdClose, orginPv, add, newCalcLast, closeList, isPenaltyInterest);
|
||
|
||
/// <summary>
|
||
/// 【EOD 当日有平仓后的收盘结息】场景(→ CalcEodPostCloseSettleInterests,settment:false 全额结息)。
|
||
/// 该场景触发 GetInterests 内 mode2 无条件覆盖 / mode9 全平兜底(见其"根因位置"注释,勿删)。
|
||
/// </summary>
|
||
/// <param name="remainingNotionalAfterClose">平仓【后】剩余本金(GetInterests.posiNotionalValue 形参位)。</param>
|
||
/// <param name="closedNotional">本次实际平掉本金。</param>
|
||
public static InterestCalcRequest EodPostCloseSettle(
|
||
trade td, trade_extend tradeExtend, DateTime valueDate, DateTime unwindDate,
|
||
List<eod_swap_position> eodPositions, List<swap_position> 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);
|
||
}
|