// https://www.mql5.com/ru/forum/1111/page2440#comment_11395809
//+------------------------------------------------------------------+
//| Structure for trade statistics                                   |
//+------------------------------------------------------------------+
struct ExpTradeSummary
{
public:
  long Pass;

  double            initial_deposit;     // initial deposit
  double            withdrawal;          // withdrawal amount
  double            profit;              // profit (+)
  double            grossprofit;         // gross profit
  double            grossloss;           // gross loss
  double            maxprofit;           // the most profitable trade
  double            minprofit;           // the most losing trade
  double            conprofitmax;        // the profit from a longest series of profitable deals
  double            maxconprofit;        // the highest profit among the profitable series
  double            conlossmax;          // the loss from a longest series of losing deals
  double            maxconloss;          // the highest loss among the losing series
  double            balance_min;         // the minimum balance value (for calculating the absolute drawdown)
  double            maxdrawdown;         // the maximum balance drawdown
  double            drawdownpercent;     // the ratio of the maximum balance drawdown to the highest value
  double            reldrawdown;         // maximum relative balance drawdown in money
  double            reldrawdownpercent;  // maximum relative balance drawdown in percent
  double            equity_min;          // the minimum equity value (for calculating the absolute equity drawdown)
  double            maxdrawdown_e;       // the maximum equity drawdown
  double            drawdownpercent_e;   // the ratio of the maximum equity drawdown to the highest value
  double            reldrawdown_e;       // maximum relative equity drawdown in money
  double            reldrawdownpercnt_e; // maximum relative equity drawdown in percent
  double            expected_payoff;     // expected payoff (+)
  double            profit_factor;       // profit factor (+)
  double            recovery_factor;     // recovery factor (+)
  double            sharpe_ratio;        // Sharpe ratio (+)
  double            margin_level;        // minimum margin level
  double            custom_fitness;      // custom fitness - OnTester result (+)
  int               deals;               // the total number of deals
  int               trades;              // the number of out/inout deals
  int               profittrades;        // the number of profitable deals
  int               losstrades;          // the number of losing deals
  int               shorttrades;         // the number of short deals
  int               longtrades;          // the number of long deals
  int               winshorttrades;      // the number of profitable short deals
  int               winlongtrades;       // the number of profitable long deals
  int               conprofitmax_trades; // the longest series of consecutive profitable deals
  int               maxconprofit_trades; // maximum profit series
  int               conlossmax_trades;   // the longest series of consecutive losing deals
  int               maxconloss_trades;   // maximum losing series
  int               avgconwinners;       // the average number of consecutive profitable deals
  int               avgconloosers;       // the average number of consecutive losing deals

#define TOSTRING(A) #A + " = " + (string)(A) + "\n"

  string ToString( void ) const
  {
    return(
      TOSTRING(Pass) +

      TOSTRING(initial_deposit) +      // initial deposit
      TOSTRING(withdrawal) +           // withdrawal amount
      TOSTRING(profit) +               // profit (+)
      TOSTRING(grossprofit) +          // gross profit
      TOSTRING(grossloss) +            // gross loss
      TOSTRING(maxprofit) +            // the most profitable trade
      TOSTRING(minprofit) +            // the most losing trade
      TOSTRING(conprofitmax) +         // the profit from a longest series of profitable deals
      TOSTRING(maxconprofit) +         // the highest profit among the profitable series
      TOSTRING(conlossmax) +           // the loss from a longest series of losing deals
      TOSTRING(maxconloss) +           // the highest loss among the losing series
      TOSTRING(balance_min) +          // the minimum balance value (for calculating the absolute drawdown)
      TOSTRING(maxdrawdown) +          // the maximum balance drawdown
      TOSTRING(drawdownpercent) +      // the ratio of the maximum balance drawdown to the highest value
      TOSTRING(reldrawdown) +          // maximum relative balance drawdown in money
      TOSTRING(reldrawdownpercent) +   // maximum relative balance drawdown in percent
      TOSTRING(equity_min) +           // the minimum equity value (for calculating the absolute equity drawdown)
      TOSTRING(maxdrawdown_e) +        // the maximum equity drawdown
      TOSTRING(drawdownpercent_e) +    // the ratio of the maximum equity drawdown to the highest value
      TOSTRING(reldrawdown_e) +        // maximum relative equity drawdown in money
      TOSTRING(reldrawdownpercnt_e) +  // maximum relative equity drawdown in percent
      TOSTRING(expected_payoff) +      // expected payoff (+)
      TOSTRING(profit_factor) +        // profit factor (+)
      TOSTRING(recovery_factor) +      // recovery factor (+)
      TOSTRING(sharpe_ratio) +         // Sharpe ratio (+)
      TOSTRING(margin_level) +         // minimum margin level
      TOSTRING(custom_fitness) +       // minimum margin level
      TOSTRING(deals) +                // the total number of deals
      TOSTRING(trades) +               // the number of out/inout deals
      TOSTRING(profittrades) +         // the number of profitable deals
      TOSTRING(losstrades) +           // the number of losing deals
      TOSTRING(shorttrades) +          // the number of short deals
      TOSTRING(longtrades) +           // the number of long deals
      TOSTRING(winshorttrades) +       // the number of profitable short deals
      TOSTRING(winlongtrades) +        // the number of profitable long deals
      TOSTRING(conprofitmax_trades) +  // the longest series of consecutive profitable deals
      TOSTRING(maxconprofit_trades) +  // maximum profit series
      TOSTRING(conlossmax_trades) +    // the longest series of consecutive losing deals
      TOSTRING(maxconloss_trades) +    // maximum losing series
      TOSTRING(avgconwinners) +        // the average number of consecutive profitable deals
      TOSTRING(avgconloosers)          // the average number of consecutive losing deals
    );
  }

  double TesterStatistics( const ENUM_STATISTICS Statistic_ID ) const
  {
    switch (Statistic_ID)
    {
      case STAT_INITIAL_DEPOSIT:
        return(this.initial_deposit);
      case STAT_WITHDRAWAL:
        return(this.withdrawal);
      case STAT_PROFIT:
        return(this.profit);
      case STAT_GROSS_PROFIT:
        return(this.grossprofit);
      case STAT_GROSS_LOSS:
        return(-this.grossloss);
      case STAT_MAX_PROFITTRADE:
        return(this.maxprofit);
      case STAT_MAX_LOSSTRADE:
        return(-this.minprofit);
      case STAT_CONPROFITMAX:
        return(this.maxconprofit);
      case STAT_CONPROFITMAX_TRADES:
        return(this.maxconprofit_trades);
      case STAT_MAX_CONWINS:
        return(this.conprofitmax);
      case STAT_MAX_CONPROFIT_TRADES:
        return(this.conprofitmax_trades);
      case STAT_CONLOSSMAX:
        return(-this.conlossmax);
      case STAT_CONLOSSMAX_TRADES:
        return(this.conlossmax_trades);
      case STAT_MAX_CONLOSSES:
        return(-this.maxconloss);
      case STAT_MAX_CONLOSS_TRADES:
        return(this.maxconloss_trades);
      case STAT_BALANCEMIN:
        return(this.balance_min);
      case STAT_BALANCE_DD:
        return(this.maxdrawdown);
      case STAT_BALANCEDD_PERCENT:
        return(this.drawdownpercent);
      case STAT_BALANCE_DDREL_PERCENT:
        return(this.reldrawdownpercent);
      case STAT_BALANCE_DD_RELATIVE:
        return(this.reldrawdown);
      case STAT_EQUITYMIN:
        return(this.equity_min);
      case STAT_EQUITY_DD:
        return(this.maxdrawdown_e);
      case STAT_EQUITYDD_PERCENT:
        return(this.drawdownpercent_e);
      case STAT_EQUITY_DDREL_PERCENT:
        return(this.reldrawdownpercnt_e);
      case STAT_EQUITY_DD_RELATIVE:
        return(this.reldrawdown_e);
      case STAT_EXPECTED_PAYOFF:
        return(this.expected_payoff);
      case STAT_PROFIT_FACTOR:
        return(this.profit_factor);
      case STAT_RECOVERY_FACTOR:
        return(this.recovery_factor);
      case STAT_SHARPE_RATIO:
        return(this.sharpe_ratio);
      case STAT_MIN_MARGINLEVEL:
        return(this.margin_level);
      case STAT_CUSTOM_ONTESTER:
        return(this.custom_fitness);
      case STAT_DEALS:
        return(this.deals);
      case STAT_TRADES:
        return(this.trades);
      case STAT_PROFIT_TRADES:
        return(this.profittrades);
      case STAT_LOSS_TRADES:
        return(this.losstrades);
      case STAT_SHORT_TRADES:
        return(this.shorttrades);
      case STAT_LONG_TRADES:
        return(this.longtrades);
      case STAT_PROFIT_SHORTTRADES:
        return(this.winshorttrades);
      case STAT_PROFIT_LONGTRADES:
        return(this.winlongtrades);
      case STAT_PROFITTRADES_AVGCON:
        return(this.avgconwinners);
      case STAT_LOSSTRADES_AVGCON:
        return(this.avgconloosers);
    }

    return(0);
  }

#undef TOSTRING
};