using System; using System.IO; using System.Linq; using System.Text.Json; using FinlyticCore.Models.Analyzer; using FinlyticCore.Models.Trades; using Microsoft.Extensions.Logging; namespace FinlyticAnalyzer.Services; public class WinRateCalculator : IWinRateCalculator { private readonly ILogger _logger; private readonly string _feedbackDir; public WinRateCalculator(ILogger logger) { _logger = logger; _feedbackDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "data", "feedback"); if (!Directory.Exists(_feedbackDir)) { Directory.CreateDirectory(_feedbackDir); } } /// /// Calculates the win rate for a given sector and symbol under the specified market regime. /// public double CalculateWinRate(string sector, string symbol, VixMarketRegime regime) { try { if (!Directory.Exists(_feedbackDir)) return 65.0; var jsonFiles = Directory.GetFiles(_feedbackDir, "*.json", SearchOption.AllDirectories); if (jsonFiles.Length == 0) return 65.0; int totalTrades = 0; int winningTrades = 0; foreach (var file in jsonFiles) { var content = File.ReadAllText(file); var records = JsonSerializer.Deserialize(content); if (records == null || records.Length == 0) continue; var matching = records.Where(r => string.Equals(r.Sector, sector, StringComparison.OrdinalIgnoreCase) && r.VixRegime == regime).ToList(); foreach (var rec in matching) { totalTrades++; if (rec.IsWin) winningTrades++; } } if (totalTrades > 0) { double calculatedWinRate = (double)winningTrades / totalTrades * 100.0; _logger.LogInformation("[{Channel}] Calculated win-rate for Sector '{Sector}' in Regime '{Regime}': {WinRate:F1}% ({Wins}/{Total})", "AnalyzerChannel", sector, regime, calculatedWinRate, winningTrades, totalTrades); return Math.Round(calculatedWinRate, 1); } } catch (Exception ex) { _logger.LogWarning(ex, "[{Channel}] Error reading feedback files for win-rate calculation. Falling back to default.", "AnalyzerChannel"); } return 65.0; // Default baseline win-rate } }