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:
190
tests/NT8.Core.Tests/Orders/OrderManagerTests.cs
Normal file
190
tests/NT8.Core.Tests/Orders/OrderManagerTests.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NT8.Core.Orders;
|
||||
using NT8.Core.Risk;
|
||||
using NT8.Core.Sizing;
|
||||
using NT8.Core.Common.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NT8.Core.Tests.Orders
|
||||
{
|
||||
[TestClass]
|
||||
public class OrderManagerTests
|
||||
{
|
||||
private TestRiskManager _testRiskManager;
|
||||
private TestPositionSizer _testPositionSizer;
|
||||
private TestLogger _testLogger;
|
||||
private OrderManager _orderManager;
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInitialize()
|
||||
{
|
||||
_testRiskManager = new TestRiskManager();
|
||||
_testPositionSizer = new TestPositionSizer();
|
||||
_testLogger = new TestLogger();
|
||||
|
||||
_orderManager = new OrderManager(
|
||||
_testRiskManager,
|
||||
_testPositionSizer,
|
||||
_testLogger);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task SubmitOrderAsync_WithValidRequest_ReturnsSuccess()
|
||||
{
|
||||
// Arrange
|
||||
var algorithmParameters = new Dictionary<string, object>();
|
||||
var request = new OrderRequest(
|
||||
"ES",
|
||||
NT8.Core.Orders.OrderSide.Buy,
|
||||
NT8.Core.Orders.OrderType.Market,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
NT8.Core.Orders.TimeInForce.Day,
|
||||
null,
|
||||
algorithmParameters
|
||||
);
|
||||
|
||||
var customData = new Dictionary<string, object>();
|
||||
var context = new StrategyContext(
|
||||
"ES",
|
||||
DateTime.UtcNow,
|
||||
new Position("ES", 0, 0, 0, 0, DateTime.UtcNow),
|
||||
new AccountInfo(10000, 100, 0, 0, DateTime.UtcNow),
|
||||
new MarketSession(DateTime.UtcNow, DateTime.UtcNow.AddHours(8), true, "RTH"),
|
||||
customData
|
||||
);
|
||||
|
||||
// Act
|
||||
var result = await _orderManager.SubmitOrderAsync(request, context);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.IsNotNull(result.OrderId);
|
||||
Assert.AreEqual("Order submitted successfully", result.Message);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task GetRoutingConfig_ReturnsConfig()
|
||||
{
|
||||
// Act
|
||||
var config = _orderManager.GetRoutingConfig();
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(config);
|
||||
Assert.IsTrue(config.SmartRoutingEnabled);
|
||||
Assert.AreEqual("Primary", config.DefaultVenue);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void UpdateRoutingConfig_WithValidConfig_UpdatesConfig()
|
||||
{
|
||||
// Arrange
|
||||
var venuePreferences = new Dictionary<string, double>();
|
||||
venuePreferences.Add("TestVenue", 1.0);
|
||||
|
||||
var newConfig = new RoutingConfig(
|
||||
false, // SmartRoutingEnabled
|
||||
"TestVenue", // DefaultVenue
|
||||
venuePreferences,
|
||||
1.0, // MaxSlippagePercent
|
||||
TimeSpan.FromSeconds(60), // MaxRoutingTime
|
||||
false, // RouteByCost
|
||||
false, // RouteBySpeed
|
||||
false // RouteByReliability
|
||||
);
|
||||
|
||||
// Act
|
||||
_orderManager.UpdateRoutingConfig(newConfig);
|
||||
var config = _orderManager.GetRoutingConfig();
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(config);
|
||||
Assert.IsFalse(config.SmartRoutingEnabled);
|
||||
Assert.AreEqual("TestVenue", config.DefaultVenue);
|
||||
Assert.AreEqual(1.0, config.MaxSlippagePercent);
|
||||
}
|
||||
|
||||
#region Test Implementations
|
||||
|
||||
/// <summary>
|
||||
/// Test implementation of IRiskManager
|
||||
/// </summary>
|
||||
private class TestRiskManager : IRiskManager
|
||||
{
|
||||
public RiskDecision ValidateOrder(StrategyIntent intent, StrategyContext context, RiskConfig config)
|
||||
{
|
||||
// Always approve for testing
|
||||
var metrics = new Dictionary<string, object>();
|
||||
return new RiskDecision(true, null, null, RiskLevel.Low, metrics);
|
||||
}
|
||||
|
||||
public void OnFill(OrderFill fill)
|
||||
{
|
||||
// No-op for testing
|
||||
}
|
||||
|
||||
public void OnPnLUpdate(double netPnL, double dayPnL)
|
||||
{
|
||||
// No-op for testing
|
||||
}
|
||||
|
||||
public async Task<bool> EmergencyFlatten(string reason)
|
||||
{
|
||||
// Always succeed for testing
|
||||
return true;
|
||||
}
|
||||
|
||||
public RiskStatus GetRiskStatus()
|
||||
{
|
||||
var alerts = new List<string>();
|
||||
return new RiskStatus(true, 0, 1000, 0, 0, DateTime.UtcNow, alerts);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test implementation of IPositionSizer
|
||||
/// </summary>
|
||||
private class TestPositionSizer : IPositionSizer
|
||||
{
|
||||
public SizingResult CalculateSize(StrategyIntent intent, StrategyContext context, SizingConfig config)
|
||||
{
|
||||
// Return fixed size for testing
|
||||
var calculations = new Dictionary<string, object>();
|
||||
return new SizingResult(1, 100, SizingMethod.FixedContracts, calculations);
|
||||
}
|
||||
|
||||
public SizingMetadata GetMetadata()
|
||||
{
|
||||
var requiredParameters = new List<string>();
|
||||
return new SizingMetadata("TestSizer", "Test position sizer", requiredParameters);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test implementation of ILogger
|
||||
/// </summary>
|
||||
private class TestLogger : ILogger<OrderManager>
|
||||
{
|
||||
public IDisposable BeginScope<TState>(TState state)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
{
|
||||
// No-op for testing
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user