//+------------------------------------------------------------------+
//|                                            TradeTablePrinter.mqh |
//+------------------------------------------------------------------+
#ifndef TRADETABLEPRINTER_MQH
#define TRADETABLEPRINTER_MQH

#include "ScatterTypes.mqh"

//+------------------------------------------------------------------+
//| CTradeTablePrinter                                               |
//| Prints a per-symbol summary table to the Experts tab: trade      |
//| count, average duration, and average profit for each symbol.     |
//+------------------------------------------------------------------+
class CTradeTablePrinter
  {
private:
   string                PadRight(string value, int width) const;

public:
                     CTradeTablePrinter(void);
                    ~CTradeTablePrinter(void);

   void                  Print(const CTradePoint &trades[], int count) const;
  };

//+------------------------------------------------------------------+
//| Constructor: no member state to initialize.                      |
//+------------------------------------------------------------------+
CTradeTablePrinter::CTradeTablePrinter(void)
  {
  }

//+------------------------------------------------------------------+
//| Destructor: no dynamic resources to release.                     |
//+------------------------------------------------------------------+
CTradeTablePrinter::~CTradeTablePrinter(void)
  {
  }

//+------------------------------------------------------------------+
//| Print                                                            |
//| Groups trades by symbol and prints one row per symbol with the   |
//| trade count, average duration in minutes, and average profit.    |
//+------------------------------------------------------------------+
void CTradeTablePrinter::Print(const CTradePoint &trades[], int count) const
  {
   string symbols[];
   double dur_sum[];
   double pnl_sum[];
   int    trade_count[];
   ::ArrayResize(symbols, 0);
//--- accumulate duration and profit totals per distinct symbol
   for(int i = 0; i < count; i++)
     {
      int idx = -1;
      int n   = ::ArraySize(symbols);
      for(int j = 0; j < n; j++)
        {
         if(symbols[j] == trades[i].symbol)
           {
            idx = j;
            break;
           }
        }
      if(idx == -1)
        {
         ::ArrayResize(symbols,     n + 1);
         ::ArrayResize(dur_sum,     n + 1);
         ::ArrayResize(pnl_sum,     n + 1);
         ::ArrayResize(trade_count, n + 1);
         symbols[n]     = trades[i].symbol;
         dur_sum[n]     = trades[i].duration_minutes;
         pnl_sum[n]     = trades[i].profit;
         trade_count[n] = 1;
        }
      else
        {
         dur_sum[idx] += trades[i].duration_minutes;
         pnl_sum[idx] += trades[i].profit;
         trade_count[idx]++;
        }
     }
//--- print the header row with fixed-width column labels
   string header = PadRight("Symbol", 12) + PadRight("Trades", 10) +
                   PadRight("Avg Dur(min)", 14) + PadRight("Avg Profit", 14);
   ::Print(header);
//--- print one row per symbol
   int symbol_count = ::ArraySize(symbols);
   for(int i = 0; i < symbol_count; i++)
     {
      double avg_dur = dur_sum[i] / trade_count[i];
      double avg_pnl = pnl_sum[i] / trade_count[i];
      string row = PadRight(symbols[i], 12) +
                   PadRight(::IntegerToString(trade_count[i]), 10) +
                   PadRight(::DoubleToString(avg_dur, 1), 14) +
                   PadRight(::DoubleToString(avg_pnl, 2), 14);
      ::Print(row);
     }
  }

//+------------------------------------------------------------------+
//| PadRight                                                         |
//| Pads a string with trailing spaces up to the given width, or     |
//| returns the original string unchanged if it already meets or     |
//| exceeds that width.                                              |
//+------------------------------------------------------------------+
string CTradeTablePrinter::PadRight(string value, int width) const
  {
   int need = width - ::StringLen(value);
   if(need <= 0)
      return(value);
   string result = value;
   for(int i = 0; i < need; i++)
      result += " ";
   return(result);
  }

#endif // TRADETABLEPRINTER_MQH
//+------------------------------------------------------------------+