Files
zszq-trs/YLErpDAL/Modules/SwapModule/Margin/SwapAdditionalMarginCalc.cs
T

44 lines
2.4 KiB
C#

namespace YLErp.Modules.SwapModule.Margin
{
/// <summary>
/// R3 阶段四 §4.1 合约维度追加保证金的纯函数(金额判定与授信/现金分配,DB 胶水在 SwapAdditionalMarginService)。
/// 口径(实现方案 §0 基线 + 需求拆分 R3):
/// - 累计保证金(净收取为正)= 该交易 应付预付金+追加保证金 资金记录收付净额 + 追加保证金的授信占用部分(授信不进资金、无流水);
/// - 目标追加保证金(累计到当日)= 维持保证金 − 应付预付金净收额,≤0 时为 0(追保回落不返还,负缺口在可用资金公式体现);
/// - 已补足额 = 追加资金记录累计值(单条 upsert 存累计值,Money 为负)+ 授信占用累计(amount 为负);
/// - 当日新增 = 目标 − 已补足,&gt;0 时按阶段二 §2.3 授信优先逻辑分配:授信部分只写授信出入表,差额走资金记录。
/// 幂等:同一结算日重跑时 目标/已补足 均不变 → 新增=0,不产生任何写入。
/// </summary>
public static class SwapAdditionalMarginCalc
{
/// <summary>
/// 目标追加保证金(累计到当日,净收取为正)= 维持保证金 − 应付预付金净收额;差值 ≤0 返回 0(无需追加;
/// 维持为负=我方净支付方向,同样不追)。
/// </summary>
public static double CalcTarget(double maintenanceMargin, double payableMarginNet)
{
return Round(Math.Max(maintenanceMargin - payableMarginNet, 0));
}
/// <summary>
/// 当日新增追加保证金的授信/现金分配(阶段二 §2.3 授信优先的交易级版本):
/// 授信部分 = min(新增, 剩余可用授信),差额为现金部分;新增 ≤0 时两者皆 0(不产生)。
/// </summary>
public static (double CreditAmount, double CashAmount) Allocate(double increment, double creditAvailable)
{
increment = Round(increment);
if (increment <= 0)
{
return (0, 0);
}
var credit = Math.Min(increment, Round(Math.Max(creditAvailable, 0)));
return (credit, Round(increment - credit));
}
private static double Round(double value)
{
return Math.Round(value, 2, MidpointRounding.AwayFromZero);
}
}
}