using Microsoft.VisualStudio.TestTools.UnitTesting; using NT8.Core.Common.Models; using NT8.Core.Risk; namespace NT8.Core.Tests.Risk { [TestClass] public class PortfolioRiskManagerTests { private PortfolioRiskManager _manager; [TestInitialize] public void TestInitialize() { _manager = PortfolioRiskManager.Instance; } [TestCleanup] public void TestCleanup() { _manager.UnregisterStrategy("strat1"); _manager.UnregisterStrategy("strat2"); _manager.UnregisterStrategy("strat3"); _manager.UnregisterStrategy("strat4"); _manager.UnregisterStrategy("strat5"); _manager.PortfolioKillSwitch = false; _manager.PortfolioDailyLossLimit = 2000.0; _manager.MaxTotalOpenContracts = 6; _manager.ResetDaily(); } [TestMethod] public void PortfolioDailyLossLimit_WhenBreached_BlocksNewOrder() { // Arrange _manager.RegisterStrategy("strat1", TestDataBuilder.CreateTestRiskConfig()); _manager.PortfolioDailyLossLimit = 500; _manager.ReportPnL("strat1", -501); var intent = TestDataBuilder.CreateValidIntent(); // Act var decision = _manager.ValidatePortfolioRisk("strat1", intent); // Assert Assert.IsFalse(decision.Allow); } [TestMethod] public void MaxTotalOpenContracts_WhenAtCap_BlocksNewOrder() { // Arrange _manager.RegisterStrategy("strat1", TestDataBuilder.CreateTestRiskConfig()); _manager.MaxTotalOpenContracts = 2; var fill1 = new OrderFill("ord1", "ES", 1, 5000.0, System.DateTime.UtcNow, 0.0, "exec1"); var fill2 = new OrderFill("ord2", "ES", 1, 5001.0, System.DateTime.UtcNow, 0.0, "exec2"); _manager.ReportFill("strat1", fill1); _manager.ReportFill("strat1", fill2); var intent = TestDataBuilder.CreateValidIntent(); // Act var decision = _manager.ValidatePortfolioRisk("strat1", intent); // Assert Assert.IsFalse(decision.Allow); } [TestMethod] public void PortfolioKillSwitch_WhenTrue_BlocksAllOrders() { // Arrange _manager.RegisterStrategy("strat1", TestDataBuilder.CreateTestRiskConfig()); _manager.PortfolioKillSwitch = true; var intent = TestDataBuilder.CreateValidIntent(); // Act var decision = _manager.ValidatePortfolioRisk("strat1", intent); // Assert Assert.IsFalse(decision.Allow); Assert.IsTrue(decision.RejectReason.ToLowerInvariant().Contains("kill switch")); } [TestMethod] public void ValidatePortfolioRisk_WhenWithinLimits_Passes() { // Arrange _manager.RegisterStrategy("strat1", TestDataBuilder.CreateTestRiskConfig()); var intent = TestDataBuilder.CreateValidIntent(); // Act var decision = _manager.ValidatePortfolioRisk("strat1", intent); // Assert Assert.IsTrue(decision.Allow); } [TestMethod] public void ResetDaily_ClearsPnL_UnblocksTrading() { // Arrange _manager.RegisterStrategy("strat1", TestDataBuilder.CreateTestRiskConfig()); _manager.PortfolioDailyLossLimit = 500; _manager.ReportPnL("strat1", -600); var intent = TestDataBuilder.CreateValidIntent(); // Act var blocked = _manager.ValidatePortfolioRisk("strat1", intent); _manager.ResetDaily(); var unblocked = _manager.ValidatePortfolioRisk("strat1", intent); // Assert Assert.IsFalse(blocked.Allow); Assert.IsTrue(unblocked.Allow); } } }