using Microsoft.VisualStudio.TestTools.UnitTesting; using NT8.Core.Logging; using NT8.Core.Sizing; using System; using System.Collections.Generic; namespace NT8.Core.Tests.Sizing { [TestClass] public class OptimalFCalculatorTests { [TestMethod] public void Constructor_NullLogger_ThrowsArgumentNullException() { // Act & Assert Assert.ThrowsException(() => new OptimalFCalculator(null)); } [TestMethod] public void Calculate_ValidInput_ReturnsValidResult() { // Arrange var calculator = new OptimalFCalculator(new BasicLogger("OptimalFCalculatorTests")); var input = new OptimalFInput( tradeResults: CreateMixedTradeResults(), maxFLimit: 0.5, stepSize: 0.01, safetyFactor: 0.8); // Act var result = calculator.Calculate(input); // Assert Assert.IsTrue(result.IsValid); Assert.IsTrue(result.OptimalF > 0.0); Assert.IsTrue(result.OptimalF <= 0.5); Assert.IsTrue(result.Confidence >= 0.0); Assert.IsTrue(result.Confidence <= 1.0); Assert.AreEqual(input.TradeResults.Count, result.TradeCount); } [TestMethod] public void Calculate_InsufficientTrades_ThrowsArgumentException() { // Arrange var calculator = new OptimalFCalculator(new BasicLogger("OptimalFCalculatorTests")); var trades = new List(); trades.Add(100); trades.Add(-50); trades.Add(80); trades.Add(-40); trades.Add(60); var input = new OptimalFInput( tradeResults: trades, maxFLimit: 1.0, stepSize: 0.01, safetyFactor: 1.0); // Act & Assert Assert.ThrowsException(() => calculator.Calculate(input)); } [TestMethod] public void Calculate_AllZeroTrades_ThrowsArgumentException() { // Arrange var calculator = new OptimalFCalculator(new BasicLogger("OptimalFCalculatorTests")); var trades = new List(); for (var i = 0; i < 12; i++) { trades.Add(0.0); } var input = new OptimalFInput( tradeResults: trades, maxFLimit: 1.0, stepSize: 0.01, safetyFactor: 1.0); // Act & Assert Assert.ThrowsException(() => calculator.Calculate(input)); } [TestMethod] public void CalculateKellyFraction_ValidTrades_ReturnsBoundedValue() { // Arrange var calculator = new OptimalFCalculator(new BasicLogger("OptimalFCalculatorTests")); var trades = CreateMixedTradeResults(); // Act var kelly = calculator.CalculateKellyFraction(trades); // Assert Assert.IsTrue(kelly >= 0.01); Assert.IsTrue(kelly <= 0.5); } [TestMethod] public void GeneratePerformanceCurve_ValidInput_ReturnsCurvePoints() { // Arrange var calculator = new OptimalFCalculator(new BasicLogger("OptimalFCalculatorTests")); var trades = CreateMixedTradeResults(); // Act var curve = calculator.GeneratePerformanceCurve(trades, 0.05); // Assert Assert.IsNotNull(curve); Assert.IsTrue(curve.Count > 0); } private static List CreateMixedTradeResults() { var trades = new List(); trades.Add(120); trades.Add(-60); trades.Add(95); trades.Add(-45); trades.Add(70); trades.Add(-30); trades.Add(140); trades.Add(-80); trades.Add(65); trades.Add(-35); trades.Add(110); trades.Add(-50); return trades; } } }