using Microsoft.VisualStudio.TestTools.UnitTesting; using YLErp.Derivatives.Interest; using YLErp.Modules.SwapModule.Margin; namespace UnitTestProject.Modules.SwapModule.Margin { /// /// 保证金账户(MarginAccount)单测。验证余额变动(追加/释放/返还)。 /// 保证金就是保证金——有余额、有利率、有利息,不存在"计息基数/Notional"概念。 /// [TestClass] public class MarginLegTest { private const decimal Opening = 2_000_000m; #region MarginAccount 余额变动 [TestMethod] public void 账户_初始余额等于期初保证金() { var account = new MarginAccount(new MarginBalance(Opening)); Assert.AreEqual(Opening, account.Balance.Balance); } [TestMethod] public void 账户_追加保证金_余额增加() { var account = new MarginAccount(new MarginBalance(Opening)); account.Deposit(500_000m); Assert.AreEqual(2_500_000m, account.Balance.Balance); } [TestMethod] public void 账户_释放保证金_余额减少() { var account = new MarginAccount(new MarginBalance(Opening)); account.Withdraw(800_000m); Assert.AreEqual(1_200_000m, account.Balance.Balance); } [TestMethod] public void 账户_释放超过余额_不低于零() { var account = new MarginAccount(new MarginBalance(Opening)); account.Withdraw(3_000_000m); Assert.AreEqual(0m, account.Balance.Balance, "保证金余额不低于零"); } #endregion #region 三种保证金形态解析器 [TestMethod] public void 三种形态解析器_各自返回正确Form和余额() { IMarginResolver cash = new CashMargin(); IMarginResolver credit = new CreditMargin(); IMarginResolver guarantee = new GuaranteeMargin(); Assert.AreEqual(MarginForm.Cash, cash.Form); Assert.AreEqual(MarginForm.Credit, credit.Form); Assert.AreEqual(MarginForm.Guarantee, guarantee.Form); Assert.AreEqual(Opening, cash.Resolve(Opening).Balance); Assert.AreEqual(Opening, credit.Resolve(Opening).Balance); Assert.AreEqual(Opening, guarantee.Resolve(Opening).Balance); } #endregion #region MarginAccount 计息 [TestMethod] public void 计息_单利7天_余额200万年化3pct() { var account = new MarginAccount(new MarginBalance(2_000_000m)); // 200万 × 3% / 365 × 7天 = 1150.68... var r = account.AccrueInterest( rate: 0.03m, startDate: new System.DateTime(2026, 5, 4), endDate: new System.DateTime(2026, 5, 11), boundary: AccrualBoundary.StartOnly, annualDays: 365); Assert.IsTrue(r.Accrued > 0, "7天利息应大于0"); System.Console.WriteLine($"保证金7天利息={r.Accrued}"); } [TestMethod] public void 计息_零余额_利息为零() { var account = new MarginAccount(new MarginBalance(0m)); var r = account.AccrueInterest(0.03m, new System.DateTime(2026, 5, 4), new System.DateTime(2026, 5, 11), AccrualBoundary.StartOnly, 365); Assert.AreEqual(0m, r.Accrued); } [TestMethod] public void 计息_释放后余额减少_利息相应减少() { var full = new MarginAccount(new MarginBalance(2_000_000m)); var half = new MarginAccount(new MarginBalance(2_000_000m)); half.Withdraw(1_000_000m); var rFull = full.AccrueInterest(0.03m, new System.DateTime(2026, 5, 4), new System.DateTime(2026, 5, 11), AccrualBoundary.StartOnly, 365); var rHalf = half.AccrueInterest(0.03m, new System.DateTime(2026, 5, 4), new System.DateTime(2026, 5, 11), AccrualBoundary.StartOnly, 365); Assert.IsTrue(rHalf.Accrued < rFull.Accrued, "释放后利息应更少"); Assert.IsTrue(System.Math.Abs(rFull.Accrued - rHalf.Accrued * 2m) < 0.01m, "余额减半, 利息也应减半"); } #endregion } }