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; _manager.UpdateOpenContracts("strat1", 2); var intent = TestDataBuilder.CreateValidIntent(); // Act var decision = _manager.ValidatePortfolioRisk("strat1", intent); // Assert Assert.IsFalse(decision.Allow); } [TestMethod] public void UpdateOpenContracts_WhenPositionCloses_UnblocksTrading() { // Arrange _manager.RegisterStrategy("strat1", TestDataBuilder.CreateTestRiskConfig()); _manager.MaxTotalOpenContracts = 6; var intent = TestDataBuilder.CreateValidIntent(); // Act _manager.UpdateOpenContracts("strat1", 6); var blocked = _manager.ValidatePortfolioRisk("strat1", intent); _manager.UpdateOpenContracts("strat1", 0); var unblocked = _manager.ValidatePortfolioRisk("strat1", intent); // Assert Assert.IsFalse(blocked.Allow); Assert.IsTrue(unblocked.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); } } }