//+------------------------------------------------------------------+
//|                                 EntryTimingAnalyzerDashboard.mq5 |
//+------------------------------------------------------------------+
#property description "Computes Maximum Adverse and Favorable Excursion and entry "
#property description "efficiency for closed positions from tick data, renders a "
#property description "MAE/MFE scatter plot and an efficiency histogram, and prints "
#property description "a summary to the Experts tab."
#property script_show_inputs

#include <EntryTimingAnalyzer/TradeExcursionTypes.mqh>
#include <EntryTimingAnalyzer/PositionHistoryReader.mqh>
#include <EntryTimingAnalyzer/ExcursionCalculator.mqh>
#include <EntryTimingAnalyzer/EfficiencyStatistics.mqh>
#include <EntryTimingAnalyzer/ExcursionScatterChart.mqh>
#include <EntryTimingAnalyzer/EfficiencyHistogramChart.mqh>
#include <EntryTimingAnalyzer/TradeTimingSummaryPrinter.mqh>

input int    InpLookbackDays  = 90; // calendar days to include, counting back from now
input string InpSymbol        = ""; // symbol to analyze; empty means the current chart symbol
input int    InpHistogramBins = 10; // number of bins in the efficiency histogram

//+---------------------------------------------------------------------+
//| Script program start function                                       |
//| Drives the full pipeline: read closed positions for one symbol,     |
//| compute MAE, MFE, and entry efficiency for each from tick data,     |
//| print the analytical summary, and render the scatter plot and the   |
//| histogram. Both chart objects are local to this function; their     |
//| destructors are intentionally empty, so both rendered panels remain |
//| visible on the chart after this function returns.                   |
//+---------------------------------------------------------------------+
void OnStart(void)
  {
//--- resolve which symbol to analyze
   string symbol = (InpSymbol == "") ? _Symbol : InpSymbol;

//--- determine the analysis window, ending at the current server time
   datetime range_to   = ::TimeCurrent();
   datetime range_from = range_to - (datetime)(InpLookbackDays * 86400);

//--- read closed positions on this symbol and group their deals
   CPositionHistoryReader history_reader;
   CTradeExcursion        trades[];
   if(!history_reader.Read(symbol, range_from, range_to, trades))
     {
      ::Print("EntryTimingAnalyzerDashboard: failed to read position history for the requested range.");
      return;
     }
   int trade_count = ::ArraySize(trades);

//--- compute MAE, MFE, and entry efficiency for every closed position
   CExcursionCalculator excursion_calculator;
   for(int i = 0; i < trade_count; i++)
      excursion_calculator.Compute(trades[i]);

//--- print the analytical summary to the Experts tab
   CTradeTimingSummaryPrinter summary_printer;
   summary_printer.Print(trades, trade_count);

//--- render the MAE vs. MFE scatter plot
   CExcursionScatterChart scatter_chart("EntryTiming_Scatter");
   scatter_chart.Draw(trades, trade_count, 20, 20, 460, 340);

//--- compute the efficiency histogram bins and mean, then render them
   CEfficiencyStatistics statistics;
   int bins[];
   statistics.ComputeHistogramBins(trades, trade_count, InpHistogramBins, bins);
   double mean_efficiency = 0.0;
   bool   mean_defined    = statistics.ComputeMeanEfficiency(trades, trade_count, mean_efficiency);

   CEfficiencyHistogramChart histogram_chart("EntryTiming_Histogram");
   histogram_chart.Draw(bins, ::ArraySize(bins), mean_efficiency, mean_defined, 500, 20, 380, 340);

//--- refresh the chart so both panels are visible immediately
   ::ChartRedraw(0);

   ::PrintFormat("EntryTimingAnalyzerDashboard: analyzed %d closed positions on %s covering %s to %s.",
                 trade_count, symbol, ::TimeToString(range_from, TIME_DATE), ::TimeToString(range_to, TIME_DATE));
  }
//+------------------------------------------------------------------+