Phase 0 completion: NT8 SDK core framework with risk management and position sizing
Some checks failed
Build and Test / build (push) Has been cancelled
Some checks failed
Build and Test / build (push) Has been cancelled
This commit is contained in:
111
tests/NT8.Core.Tests/Risk/BasicRiskManagerTests.cs
Normal file
111
tests/NT8.Core.Tests/Risk/BasicRiskManagerTests.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using NT8.Core.Risk;
|
||||
using NT8.Core.Common.Models;
|
||||
using NT8.Core.Logging;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
|
||||
namespace NT8.Core.Tests.Risk
|
||||
{
|
||||
[TestClass]
|
||||
public class BasicRiskManagerTests
|
||||
{
|
||||
private ILogger _logger;
|
||||
private BasicRiskManager _riskManager;
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInitialize()
|
||||
{
|
||||
_logger = new BasicLogger("BasicRiskManagerTests");
|
||||
_riskManager = new BasicRiskManager(_logger);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ValidateOrder_WithinLimits_ShouldAllow()
|
||||
{
|
||||
// Arrange
|
||||
var intent = TestDataBuilder.CreateValidIntent(stopTicks: 8);
|
||||
var context = TestDataBuilder.CreateTestContext();
|
||||
var config = TestDataBuilder.CreateTestRiskConfig();
|
||||
|
||||
// Act
|
||||
var result = _riskManager.ValidateOrder(intent, context, config);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result.Allow);
|
||||
Assert.IsNull(result.RejectReason);
|
||||
Assert.AreEqual(RiskLevel.Low, result.RiskLevel);
|
||||
Assert.IsTrue(result.RiskMetrics.ContainsKey("trade_risk"));
|
||||
Assert.IsTrue(result.RiskMetrics.ContainsKey("daily_pnl"));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ValidateOrder_ExceedsDailyLimit_ShouldReject()
|
||||
{
|
||||
// Arrange
|
||||
var intent = TestDataBuilder.CreateValidIntent();
|
||||
var context = TestDataBuilder.CreateTestContext();
|
||||
var config = new RiskConfig(
|
||||
dailyLossLimit: 1000,
|
||||
maxTradeRisk: 500,
|
||||
maxOpenPositions: 5,
|
||||
emergencyFlattenEnabled: true
|
||||
);
|
||||
|
||||
// Simulate daily loss exceeding limit
|
||||
_riskManager.OnPnLUpdate(0, -1001);
|
||||
|
||||
// Act
|
||||
var result = _riskManager.ValidateOrder(intent, context, config);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result.Allow);
|
||||
// Accept either "Trading halted" or "Daily loss limit" as valid rejection reasons
|
||||
Assert.IsTrue(result.RejectReason.Contains("Trading halted") || result.RejectReason.Contains("Daily loss limit breached"),
|
||||
"Expected reject reason to contain either 'Trading halted' or 'Daily loss limit breached', but got: " + result.RejectReason);
|
||||
Assert.AreEqual(RiskLevel.Critical, result.RiskLevel);
|
||||
Assert.AreEqual(-1001.0, result.RiskMetrics["daily_pnl"]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ValidateOrder_ExceedsTradeRisk_ShouldReject()
|
||||
{
|
||||
// Arrange
|
||||
var intent = TestDataBuilder.CreateValidIntent(stopTicks: 100); // High risk trade
|
||||
var context = TestDataBuilder.CreateTestContext();
|
||||
var config = new RiskConfig(
|
||||
dailyLossLimit: 10000,
|
||||
maxTradeRisk: 500, // Lower than calculated trade risk
|
||||
maxOpenPositions: 5,
|
||||
emergencyFlattenEnabled: true
|
||||
);
|
||||
|
||||
// Act
|
||||
var result = _riskManager.ValidateOrder(intent, context, config);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result.Allow);
|
||||
// Accept either "Trading halted" or "Trade risk too high" as valid rejection reasons
|
||||
Assert.IsTrue(result.RejectReason.Contains("Trading halted") || result.RejectReason.Contains("Trade risk too high"),
|
||||
"Expected reject reason to contain either 'Trading halted' or 'Trade risk too high', but got: " + result.RejectReason);
|
||||
Assert.AreEqual(RiskLevel.High, result.RiskLevel);
|
||||
|
||||
// Verify risk calculation
|
||||
var expectedRisk = 100 * 12.50; // 100 ticks * ES tick value
|
||||
Assert.AreEqual(expectedRisk, result.RiskMetrics["trade_risk"]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ValidateOrder_WithNullParameters_ShouldThrow()
|
||||
{
|
||||
// Arrange
|
||||
var intent = TestDataBuilder.CreateValidIntent();
|
||||
var context = TestDataBuilder.CreateTestContext();
|
||||
var config = TestDataBuilder.CreateTestRiskConfig();
|
||||
|
||||
// Act & Assert
|
||||
Assert.ThrowsException<ArgumentNullException>(() => _riskManager.ValidateOrder(null, context, config));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => _riskManager.ValidateOrder(intent, null, config));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => _riskManager.ValidateOrder(intent, context, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user