191 lines
6.1 KiB
C#
191 lines
6.1 KiB
C#
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
|
|
}
|
|
}
|