132 lines
6.3 KiB
C#
132 lines
6.3 KiB
C#
using YLErp.Modules.SwapModule.Margin;
|
||
|
||
namespace YLErp.Modules.SwapModule
|
||
{
|
||
/// <summary>
|
||
/// R2 阶段三 §3.2 可用资金公式测试(需求拆分 R2 口径,实时/EOD/报告三处共用 SwapSpanBalanceCalc):
|
||
/// 客户维度 = Max(现金结存 + 授信 − 已使用授信 + 初始保证金 − 维持保证金, 0);
|
||
/// 合约维度 = Max(现金结存 + 授信 − 已使用授信 − 交易维度追加保证金合计, 0)。
|
||
/// 授信额度为 credit.Credit 合计(保存时已折算比例),现金结存=期末结存(阶段二起授信不进资金)。
|
||
/// </summary>
|
||
[TestClass]
|
||
public class SwapSpanBalanceCalcTest
|
||
{
|
||
[TestMethod]
|
||
public void SB_001_客户维度_现金充足()
|
||
{
|
||
//现金200 + 授信100 − 已使用20 + 初始100 − 维持150 = 230
|
||
Assert.AreEqual(230, SwapSpanBalanceCalc.CalcClientDimensionAvailable(
|
||
cashBalance: 200, totalCredit: 100, usedCredit: 20, initialMargin: 100, maintenanceMargin: 150), 1e-6);
|
||
}
|
||
|
||
[TestMethod]
|
||
public void SB_002_客户维度_现金不足_截断为0()
|
||
{
|
||
//现金20 + 0 − 0 + 100 − 130 = −10 → 0(追加10未补足时无可用资金)
|
||
Assert.AreEqual(0, SwapSpanBalanceCalc.CalcClientDimensionAvailable(
|
||
cashBalance: 20, totalCredit: 0, usedCredit: 0, initialMargin: 100, maintenanceMargin: 130), 1e-6);
|
||
}
|
||
|
||
[TestMethod]
|
||
public void SB_003_客户维度_授信可用额参与覆盖()
|
||
{
|
||
//现金20 + 授信100 − 已使用20 + 100 − 130 = 70
|
||
Assert.AreEqual(70, SwapSpanBalanceCalc.CalcClientDimensionAvailable(
|
||
cashBalance: 20, totalCredit: 100, usedCredit: 20, initialMargin: 100, maintenanceMargin: 130), 1e-6);
|
||
}
|
||
|
||
[TestMethod]
|
||
public void SB_004_合约维度_按交易追加合计扣减()
|
||
{
|
||
//现金20 + 授信100 − 已使用20 − 追加合计30 = 70
|
||
Assert.AreEqual(70, SwapSpanBalanceCalc.CalcContractDimensionAvailable(
|
||
cashBalance: 20, totalCredit: 100, usedCredit: 20, tradeAdditionalMarginSum: 30), 1e-6);
|
||
}
|
||
|
||
[TestMethod]
|
||
public void SB_005_合约维度_扣尽截断为0()
|
||
{
|
||
Assert.AreEqual(0, SwapSpanBalanceCalc.CalcContractDimensionAvailable(
|
||
cashBalance: 20, totalCredit: 0, usedCredit: 0, tradeAdditionalMarginSum: 30), 1e-6);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 阶段三口径一致性:无追加保证金流水时(阶段四前),两维度公式数值一致——
|
||
/// 交易追加合计 = Σ(维持−累计) = 维持 − 初始,与客户维度的 (初始−维持) 项互相抵消。
|
||
/// </summary>
|
||
[TestMethod]
|
||
public void SB_006_阶段三两维度数值一致()
|
||
{
|
||
var cash = 20d;
|
||
var credit = 100d;
|
||
var used = 20d;
|
||
var initial = 100d;
|
||
var maintenance = 130d;
|
||
var clientDimension = SwapSpanBalanceCalc.CalcClientDimensionAvailable(cash, credit, used, initial, maintenance);
|
||
var contractDimension = SwapSpanBalanceCalc.CalcContractDimensionAvailable(cash, credit, used, maintenance - initial);
|
||
Assert.AreEqual(clientDimension, contractDimension, 1e-9);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 阶段四 §4.2 客户维度双向追保:正数=需追保,不以 0 截断。
|
||
/// </summary>
|
||
[TestMethod]
|
||
public void SB_010_客户维度追保金额_正数需追保()
|
||
{
|
||
//追保差额 (维持150 − 初始100)=50;资金 现金5+授信0−已使用0=5 → 追保 = 50 − 5 = 45
|
||
Assert.AreEqual(45, SwapSpanBalanceCalc.CalcClientDimensionCallMargin(
|
||
cashBalance: 5, totalCredit: 0, usedCredit: 0, initialMargin: 100, maintenanceMargin: 150), 1e-6);
|
||
}
|
||
|
||
[TestMethod]
|
||
public void SB_011_客户维度追保金额_负数可返还()
|
||
{
|
||
//差额 (维持130−初始100)=30,资金 20+100−20=100 → 追保 = 30 − 100 = −70(可返还,不截断为 0)
|
||
Assert.AreEqual(-70, SwapSpanBalanceCalc.CalcClientDimensionCallMargin(
|
||
cashBalance: 20, totalCredit: 100, usedCredit: 20, initialMargin: 100, maintenanceMargin: 130), 1e-6);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 客户维度追保金额与可用资金公式互为反向(去 Max 截断):追保 = −(未截断可用资金)。
|
||
/// </summary>
|
||
[TestMethod]
|
||
public void SB_012_客户维度追保与可用资金反向一致()
|
||
{
|
||
var cash = 20d;
|
||
var credit = 100d;
|
||
var used = 20d;
|
||
var initial = 100d;
|
||
var maintenance = 130d;
|
||
var available = SwapSpanBalanceCalc.CalcClientDimensionAvailable(cash, credit, used, initial, maintenance);
|
||
var callMargin = SwapSpanBalanceCalc.CalcClientDimensionCallMargin(cash, credit, used, initial, maintenance);
|
||
var availableUnfloored = cash + credit - used + initial - maintenance;
|
||
Assert.AreEqual(-availableUnfloored, callMargin, 1e-9);
|
||
//可用资金被 0 截断时追保为正(需追保),两者不矛盾
|
||
if (availableUnfloored < 0)
|
||
{
|
||
Assert.AreEqual(0, available, 1e-9);
|
||
Assert.IsTrue(callMargin > 0);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 合约维度追保金额(需求原文 现金+授信−已使用 的应追加方向取值):账户透支为正=应补足,盈余为负。
|
||
/// </summary>
|
||
[TestMethod]
|
||
public void SB_013_合约维度追保金额_透支为正()
|
||
{
|
||
//现金−80 + 授信100 − 已使用30 = −10 → 追保 = 10(应补足)
|
||
Assert.AreEqual(10, SwapSpanBalanceCalc.CalcContractDimensionCallMargin(
|
||
cashBalance: -80, totalCredit: 100, usedCredit: 30), 1e-6);
|
||
}
|
||
|
||
[TestMethod]
|
||
public void SB_014_合约维度追保金额_盈余为负()
|
||
{
|
||
//现金50 + 授信100 − 已使用20 = 130 → 追保 = −130(盈余可返还方向)
|
||
Assert.AreEqual(-130, SwapSpanBalanceCalc.CalcContractDimensionCallMargin(
|
||
cashBalance: 50, totalCredit: 100, usedCredit: 20), 1e-6);
|
||
}
|
||
}
|
||
}
|