Some checks failed
Build and Test / build (push) Has been cancelled
Analytics Layer (15 components): - TradeRecorder: Full trade lifecycle tracking with partial fills - PerformanceCalculator: Sharpe, Sortino, win rate, profit factor, expectancy - PnLAttributor: Multi-dimensional attribution (grade/regime/time/strategy) - DrawdownAnalyzer: Period detection and recovery metrics - GradePerformanceAnalyzer: Grade-level edge analysis - RegimePerformanceAnalyzer: Regime segmentation and transitions - ConfluenceValidator: Factor validation and weighting optimization - ReportGenerator: Daily/weekly/monthly reporting with export - TradeBlotter: Real-time trade ledger with filtering - ParameterOptimizer: Grid search and walk-forward scaffolding - MonteCarloSimulator: Confidence intervals and risk-of-ruin - PortfolioOptimizer: Multi-strategy allocation and portfolio metrics Test Coverage (90 new tests): - 240+ total tests, 100% pass rate - >85% code coverage - Zero new warnings Project Status: Phase 5 complete (85% overall), ready for NT8 integration
195 lines
6.3 KiB
C#
195 lines
6.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using NT8.Core.Intelligence;
|
|
using NT8.Core.Logging;
|
|
|
|
namespace NT8.Core.Analytics
|
|
{
|
|
/// <summary>
|
|
/// Grade-level aggregate analysis report.
|
|
/// </summary>
|
|
public class GradePerformanceReport
|
|
{
|
|
/// <summary>
|
|
/// Metrics by grade.
|
|
/// </summary>
|
|
public Dictionary<TradeGrade, PerformanceMetrics> MetricsByGrade { get; set; }
|
|
|
|
/// <summary>
|
|
/// Accuracy by grade.
|
|
/// </summary>
|
|
public Dictionary<TradeGrade, double> GradeAccuracy { get; set; }
|
|
|
|
/// <summary>
|
|
/// Suggested threshold.
|
|
/// </summary>
|
|
public TradeGrade SuggestedThreshold { get; set; }
|
|
|
|
/// <summary>
|
|
/// Creates a report instance.
|
|
/// </summary>
|
|
public GradePerformanceReport()
|
|
{
|
|
MetricsByGrade = new Dictionary<TradeGrade, PerformanceMetrics>();
|
|
GradeAccuracy = new Dictionary<TradeGrade, double>();
|
|
SuggestedThreshold = TradeGrade.F;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Analyzes performance by confluence grade.
|
|
/// </summary>
|
|
public class GradePerformanceAnalyzer
|
|
{
|
|
private readonly ILogger _logger;
|
|
private readonly PerformanceCalculator _calculator;
|
|
|
|
/// <summary>
|
|
/// Initializes analyzer.
|
|
/// </summary>
|
|
/// <param name="logger">Logger dependency.</param>
|
|
public GradePerformanceAnalyzer(ILogger logger)
|
|
{
|
|
if (logger == null)
|
|
throw new ArgumentNullException("logger");
|
|
|
|
_logger = logger;
|
|
_calculator = new PerformanceCalculator(logger);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Produces grade-level performance report.
|
|
/// </summary>
|
|
/// <param name="trades">Trade records.</param>
|
|
/// <returns>Performance report.</returns>
|
|
public GradePerformanceReport AnalyzeByGrade(List<TradeRecord> trades)
|
|
{
|
|
if (trades == null)
|
|
throw new ArgumentNullException("trades");
|
|
|
|
try
|
|
{
|
|
var report = new GradePerformanceReport();
|
|
foreach (TradeGrade grade in Enum.GetValues(typeof(TradeGrade)))
|
|
{
|
|
var subset = trades.Where(t => t.Grade == grade).ToList();
|
|
report.MetricsByGrade[grade] = _calculator.Calculate(subset);
|
|
report.GradeAccuracy[grade] = CalculateGradeAccuracy(grade, trades);
|
|
}
|
|
|
|
report.SuggestedThreshold = FindOptimalThreshold(trades);
|
|
return report;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError("AnalyzeByGrade failed: {0}", ex.Message);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates percentage of profitable trades for a grade.
|
|
/// </summary>
|
|
/// <param name="grade">Target grade.</param>
|
|
/// <param name="trades">Trade records.</param>
|
|
/// <returns>Accuracy in range [0,1].</returns>
|
|
public double CalculateGradeAccuracy(TradeGrade grade, List<TradeRecord> trades)
|
|
{
|
|
if (trades == null)
|
|
throw new ArgumentNullException("trades");
|
|
|
|
try
|
|
{
|
|
var subset = trades.Where(t => t.Grade == grade).ToList();
|
|
if (subset.Count == 0)
|
|
return 0.0;
|
|
|
|
var winners = subset.Count(t => t.RealizedPnL > 0.0);
|
|
return (double)winners / subset.Count;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError("CalculateGradeAccuracy failed: {0}", ex.Message);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finds threshold with best expectancy for accepted grades and above.
|
|
/// </summary>
|
|
/// <param name="trades">Trade records.</param>
|
|
/// <returns>Suggested threshold grade.</returns>
|
|
public TradeGrade FindOptimalThreshold(List<TradeRecord> trades)
|
|
{
|
|
if (trades == null)
|
|
throw new ArgumentNullException("trades");
|
|
|
|
try
|
|
{
|
|
var ordered = new List<TradeGrade>
|
|
{
|
|
TradeGrade.APlus,
|
|
TradeGrade.A,
|
|
TradeGrade.B,
|
|
TradeGrade.C,
|
|
TradeGrade.D,
|
|
TradeGrade.F
|
|
};
|
|
|
|
var bestGrade = TradeGrade.F;
|
|
var bestExpectancy = double.MinValue;
|
|
|
|
foreach (var threshold in ordered)
|
|
{
|
|
var accepted = trades.Where(t => (int)t.Grade >= (int)threshold).ToList();
|
|
if (accepted.Count == 0)
|
|
continue;
|
|
|
|
var expectancy = _calculator.CalculateExpectancy(accepted);
|
|
if (expectancy > bestExpectancy)
|
|
{
|
|
bestExpectancy = expectancy;
|
|
bestGrade = threshold;
|
|
}
|
|
}
|
|
|
|
return bestGrade;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError("FindOptimalThreshold failed: {0}", ex.Message);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets metrics grouped by grade.
|
|
/// </summary>
|
|
/// <param name="trades">Trade records.</param>
|
|
/// <returns>Metrics by grade.</returns>
|
|
public Dictionary<TradeGrade, PerformanceMetrics> GetMetricsByGrade(List<TradeRecord> trades)
|
|
{
|
|
if (trades == null)
|
|
throw new ArgumentNullException("trades");
|
|
|
|
try
|
|
{
|
|
var result = new Dictionary<TradeGrade, PerformanceMetrics>();
|
|
foreach (TradeGrade grade in Enum.GetValues(typeof(TradeGrade)))
|
|
{
|
|
var subset = trades.Where(t => t.Grade == grade).ToList();
|
|
result.Add(grade, _calculator.Calculate(subset));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError("GetMetricsByGrade failed: {0}", ex.Message);
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
}
|