//+------------------------------------------------------------------+
//|                                       RiskAnalyzerDashboard.mq5  |
//+------------------------------------------------------------------+

#property script_show_inputs

#include <RiskAnalyzer/RiskTypes.mqh>
#include <RiskAnalyzer/TradeStatsExtractor.mqh>
#include <RiskAnalyzer/StreakProbabilityCalculator.mqh>
#include <RiskAnalyzer/RiskOfRuinCalculator.mqh>
#include <RiskAnalyzer/RiskOfRuinChart.mqh>
#include <RiskAnalyzer/RiskReportPrinter.mqh>

input int    InpLookbackDays = 180;   // Number of days to look back from now
input double InpRiskPercent  = 2.0;   // Current risk per trade, as a percentage
input int    InpPanelX       = 20;    // Canvas panel X coordinate
input int    InpPanelY       = 20;    // Canvas panel Y coordinate
input int    InpPanelWidth   = 640;   // Canvas panel width in pixels
input int    InpPanelHeight  = 260;   // Canvas panel height in pixels

//+------------------------------------------------------------------+
//| OnStart                                                          |
//| Resolves the date range, reads trade statistics, builds the      |
//| streak probability table, computes the current risk of ruin and  |
//| the full ruin curve, then renders the chart and prints the       |
//| terminal log report.                                             |
//+------------------------------------------------------------------+
void OnStart(void)
  {
//--- resolve the date range from the lookback input
   datetime to_time   = ::TimeCurrent();
   datetime from_time = to_time - (InpLookbackDays * 86400);
//--- read trade statistics from closed deal history
   CTradeStatsExtractor extractor;
   CTradeStats          stats;
   int                  trade_count = extractor.Read(from_time, to_time, stats);
   if(trade_count < 2)
     {
      ::Print("RiskAnalyzer: not enough trades to compute meaningful statistics");
      return;
     }
//--- build the streak probability table for the standard reference lengths
   CStreakProbabilityCalculator streak_calc;
   int                          streak_lengths[4] = {5, 10, 15, 20};
   CStreakProbability           table[];
   int table_count = streak_calc.BuildProbabilityTable(stats.win_rate, streak_lengths, 4, table);
//--- put the account's own worst streak in the same probability context
   double historical_probability = streak_calc.ComputeStreakProbability(stats.win_rate, stats.max_loss_streak);
//--- compute risk of ruin at the current risk setting and across the full curve
   CRiskOfRuinCalculator ror_calc;
   CRiskOfRuinResult     current_ror;
   if(!ror_calc.Compute(stats.win_rate, stats.avg_win, stats.avg_loss, InpRiskPercent, current_ror))
     {
      ::Print("RiskAnalyzer: could not compute risk of ruin; InpRiskPercent must be greater than zero");
      return;
     }
   CRiskOfRuinResult curve[];
   int curve_count = ror_calc.BuildCurve(stats.win_rate, stats.avg_win, stats.avg_loss, 0.5, 20.0, 0.5, curve);
//--- render the ruin curve chart, passing the exact already-computed ruin
//--- value at the current setting rather than letting the chart approximate
//--- it from the nearest sampled point on the curve
   CRiskOfRuinChart chart;
   chart.Draw(curve, curve_count, InpRiskPercent, current_ror.ror,
              InpPanelX, InpPanelY, InpPanelWidth, InpPanelHeight);
//--- print the full report to the terminal log
   CRiskReportPrinter printer;
   printer.Print(stats, table, table_count, historical_probability, current_ror);
  }
//+------------------------------------------------------------------+