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