using System; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; using NT8.Core.Analytics; using NT8.Core.Common.Models; using NT8.Core.Intelligence; using NT8.Core.Logging; namespace NT8.Integration.Tests { [TestClass] public class Phase5IntegrationTests { private BasicLogger _logger; [TestInitialize] public void TestInitialize() { _logger = new BasicLogger("Phase5IntegrationTests"); } [TestMethod] public void EndToEnd_Recorder_ToReportGenerator_Works() { var recorder = new TradeRecorder(_logger); recorder.RecordEntry("T1", Intent(), Fill(1, 100), Score(), RiskMode.PCP); recorder.RecordExit("T1", Fill(1, 105)); var trades = recorder.GetTrades(DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1)); var generator = new ReportGenerator(_logger); var daily = generator.GenerateDailyReport(DateTime.UtcNow, trades); Assert.IsNotNull(daily); Assert.IsTrue(daily.SummaryMetrics.TotalTrades >= 1); } [TestMethod] public void EndToEnd_Attribution_GradeAnalysis_Works() { var trades = Trades(); var attributor = new PnLAttributor(_logger); var grade = attributor.AttributeByGrade(trades); var gradeAnalyzer = new GradePerformanceAnalyzer(_logger); var report = gradeAnalyzer.AnalyzeByGrade(trades); Assert.IsTrue(grade.Slices.Count > 0); Assert.IsTrue(report.MetricsByGrade.Count > 0); } [TestMethod] public void EndToEnd_Regime_Confluence_Works() { var trades = Trades(); var regime = new RegimePerformanceAnalyzer(_logger).AnalyzeByRegime(trades); var weights = new ConfluenceValidator(_logger).RecommendWeights(trades); Assert.IsTrue(regime.CombinedMetrics.Count > 0); Assert.IsTrue(weights.Count > 0); } [TestMethod] public void EndToEnd_Optimization_MonteCarlo_Portfolio_Works() { var trades = Trades(); var opt = new ParameterOptimizer(_logger); var single = opt.OptimizeParameter("x", new List { 1, 2, 3 }, trades); var mc = new MonteCarloSimulator(_logger); var sim = mc.Simulate(trades, 50, 20); var po = new PortfolioOptimizer(_logger); var alloc = po.OptimizeAllocation(Strategies()); Assert.IsNotNull(single); Assert.AreEqual(50, sim.FinalPnLDistribution.Count); Assert.IsTrue(alloc.Allocation.Count > 0); } [TestMethod] public void EndToEnd_Blotter_FilterSort_Works() { var blotter = new TradeBlotter(_logger); blotter.SetTrades(Trades()); var bySymbol = blotter.FilterBySymbol("ES"); var sorted = blotter.SortBy("pnl", SortDirection.Desc); Assert.IsTrue(bySymbol.Count > 0); Assert.IsTrue(sorted.Count > 0); } [TestMethod] public void EndToEnd_DrawdownAnalysis_Works() { var analyzer = new DrawdownAnalyzer(_logger); var report = analyzer.Analyze(Trades()); Assert.IsNotNull(report); } [TestMethod] public void EndToEnd_ReportExports_Works() { var generator = new ReportGenerator(_logger); var daily = generator.GenerateDailyReport(DateTime.UtcNow, Trades()); var text = generator.ExportToText(daily); var json = generator.ExportToJson(daily); var csv = generator.ExportToCsv(Trades()); Assert.IsTrue(text.Length > 0); Assert.IsTrue(json.Length > 0); Assert.IsTrue(csv.Length > 0); } [TestMethod] public void EndToEnd_EquityCurve_Works() { var curve = new ReportGenerator(_logger).BuildEquityCurve(Trades()); Assert.IsTrue(curve.Points.Count > 0); } [TestMethod] public void EndToEnd_RiskOfRuin_Works() { var ror = new MonteCarloSimulator(_logger).CalculateRiskOfRuin(Trades(), 30.0); Assert.IsTrue(ror >= 0.0 && ror <= 1.0); } [TestMethod] public void EndToEnd_TransitionAnalysis_Works() { var impacts = new RegimePerformanceAnalyzer(_logger).AnalyzeTransitions(Trades()); Assert.IsNotNull(impacts); } private static StrategyIntent Intent() { return new StrategyIntent("ES", OrderSide.Buy, OrderType.Market, null, 8, 16, 0.8, "test", new Dictionary()); } private static ConfluenceScore Score() { return new ConfluenceScore(0.7, 0.7, TradeGrade.B, new List(), DateTime.UtcNow, new Dictionary()); } private static OrderFill Fill(int qty, double price) { return new OrderFill("O1", "ES", qty, price, DateTime.UtcNow, 1.0, Guid.NewGuid().ToString()); } private static List Trades() { var list = new List(); for (var i = 0; i < 20; i++) { var t = new TradeRecord(); t.TradeId = i.ToString(); t.Symbol = "ES"; t.StrategyName = i % 2 == 0 ? "S1" : "S2"; t.EntryTime = DateTime.UtcNow.Date.AddMinutes(i * 10); t.ExitTime = t.EntryTime.AddMinutes(5); t.Side = OrderSide.Buy; t.Quantity = 1; t.EntryPrice = 100; t.ExitPrice = 101; t.RealizedPnL = i % 3 == 0 ? -10 : 15; t.Grade = i % 2 == 0 ? TradeGrade.A : TradeGrade.B; t.RiskMode = RiskMode.PCP; t.VolatilityRegime = i % 2 == 0 ? VolatilityRegime.Normal : VolatilityRegime.Elevated; t.TrendRegime = i % 2 == 0 ? TrendRegime.StrongUp : TrendRegime.Range; t.StopTicks = 8; t.TargetTicks = 16; t.RMultiple = t.RealizedPnL / 8.0; t.Duration = TimeSpan.FromMinutes(5); list.Add(t); } return list; } private static List Strategies() { var a = new StrategyPerformance(); a.StrategyName = "S1"; a.MeanReturn = 1.2; a.StdDevReturn = 0.9; a.Sharpe = 1.3; a.Correlations.Add("S2", 0.3); var b = new StrategyPerformance(); b.StrategyName = "S2"; b.MeanReturn = 1.0; b.StdDevReturn = 0.8; b.Sharpe = 1.25; b.Correlations.Add("S1", 0.3); return new List { a, b }; } } }