using YLErp.DBModels;
namespace YLErp.Modules.SwapModule.Margin;
///
/// 保证金计算工具。从 SwapDealService 剥离的保证金纯函数。
///
public static class MarginCalc
{
///
/// 取上一日终保证金余额。
///
/// 三级优先级(均有测试覆盖,不可简化):
/// 1. InterestPrincipalFix——EOD 归档赋值时的首选字段
/// 2. TdInterestPrincipal——部分 EOD 归档路径未写 InterestPrincipalFix(值为0),
/// 此时 TdInterestPrincipal 含正确的保证金本金(生产 eod_swap_position(35774) 即此场景)
/// 3. fallback——首次平仓(preEod.id==0, 无归档)时用当日保证金余额
///
public static decimal PreviousBalance(eod_swap_position preEod, decimal fallback)
{
var previous = preEod.InterestPrincipalFix != 0m
? preEod.InterestPrincipalFix
: preEod.TdInterestPrincipal;
return preEod.id != 0 && previous != 0m ? previous : fallback;
}
///
/// 保证金方向翻转。保证金利息是券商付给客户(方向与融资腿相反)。
///
public static int FlipDirection(int direction)
=> direction == (int)SwapDirectionEnum.收取
? (int)SwapDirectionEnum.支付
: (int)SwapDirectionEnum.收取;
///
/// 汇总保证金腿的平仓返还金额(SwapMarginAmount)和保证金返息(SwapMarginRebatePnl)。
/// 保证金方向与融资腿相反:interestRatio = InterestDirection==1 ? -1 : 1。
///
public static void AccumulateSettlement(List interestList, UnwindData unwindData)
{
foreach (var x in interestList)
{
if (!MarginModes.Contains(x.InterestMode)) continue;
var interestRatio = x.InterestDirection == 1 ? -1m : 1m;
unwindData.SwapMarginRebatePnl += x.InterestClosePnL;
unwindData.SwapMarginAmount += x.InterestPrincipal * interestRatio;
}
}
}