//+------------------------------------------------------------------+
//|                                                MultiSymbolRM.mq4 |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Evbut"
#property link "https://www.mql5.com/ru/users/evbut"
#property strict
#property indicator_chart_window

#define SYMBOLS_MAX   100
#define DEALS          0
#define SUMMLOT        1
#define MAXLOT         2
#define BUY_LOTS       3
#define SELL_LOTS      4
#define FREE_LOTS      5
#define PROFIT         6
#define prefix           "RM_"
#define txtfont         "Times New Roman"   
#define name_size      8       

input string   InpWorkInstrument    = "AUDCHF,AUDJPY,AUDNZD,AUDUSD,CADCHF,CADJPY,EURAUD,EURCAD,EURCHF,EURGBP,EURJPY,EURNZD,EURUSD,GBPAUD,GBPCAD,GBPCHF,GBPJPY,GBPUSD,NZDCHF,NZDJPY,NZDUSD,USDCAD,USDCHF,USDJPY,GOLD,SILVER"; //Symbol List
input double   InpRisk              = 0.04;        //Percent of Free Margin to Deal
input bool     InpMinLotMode        = false;       //Use Mode "Broker Min_Lot" for calculation
input int      Inptxtsize           = 12;          // Text Size (pix)
input color    InpHeadColor=clrDarkOrange; // Color of Table Head
input int      InpExtVertShift      = 18;          // Vertical Row of Text shift (pix)
input  color   InpPositive          = clrGreen;    // Color of Positive Data
input  color   InpNegative          = clrRed;      // Color of Nagative Data


string ExtSymbols[SYMBOLS_MAX];
int    ExtSymbolsTotal=0;
double ExtSymbolsSummaries[SYMBOLS_MAX][8];
int    ExtLines=-1;
string ExtCols[name_size]={0};

int    ExtShifts[name_size]={ 0,80,170,300,430,530,630,720 };

long   X=60,Y=5;             //Row Coordinate
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectsDeleteAll(0,prefix);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string GetHeadName(int number)
  {
     {
      switch(number)
        {
         case 0  : return( "Symbol");             break;
         case 1  : return("Deal");                break;
         case 2  : return("Symbol Lots");         break;
         case 3  : if(!InpMinLotMode)
                     return("Max Risk Lots");
                   else
                     return("Min Lots Number");   break;
         case 4  : return("Free Lots");           break;
         case 5  : return("Buy Lots");            break;
         case 6  : return("Sell Lots");           break;
         case 7  : return("Profit");              break;
        }
      return("");
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Analyze()
  {
   double profit;
   string sep=",";                // разделитель в виде символа 
   ushort u_sep;                  // код символа разделителя 
   u_sep=StringGetCharacter(sep,0);
   int    i,index,type,total=OrdersTotal();
   double  MoneyForDeal=0.0,marga=0.0,minlot=0.0;
//--- разобьем строку на подстроки 
   ExtSymbolsTotal=StringSplit(InpWorkInstrument,u_sep,ExtSymbols);

//----
   for(i=0; i<total; i++)
     {
      if(!OrderSelect(i,SELECT_BY_POS)) continue;
      type=OrderType();
      if(type!=OP_BUY && type!=OP_SELL) continue;
      index=SymbolsIndex(OrderSymbol());
      if(index<0 || index>=SYMBOLS_MAX) continue;
      //----
      ExtSymbolsSummaries[index][DEALS]++;
      profit=OrderProfit()+OrderCommission()+OrderSwap();
      ExtSymbolsSummaries[index][PROFIT]+=profit;
      ExtSymbolsSummaries[index][SUMMLOT]+=OrderLots();

      if(type==OP_BUY)
         ExtSymbolsSummaries[index][BUY_LOTS]+=OrderLots();
      else
         ExtSymbolsSummaries[index][SELL_LOTS]+=OrderLots();
     }

   for(int j=0; j<ExtSymbolsTotal; j++)
     {
      marga=MarketInfo(ExtSymbols[j],MODE_MARGINREQUIRED);
      minlot=MarketInfo(ExtSymbols[j],MODE_MINLOT);
      MoneyForDeal=InpRisk*AccountFreeMargin()/100;
      
      if(marga != 0 && minlot !=0)
       { 
        if(InpMinLotMode)
          {
            ExtSymbolsSummaries[j][MAXLOT]=MoneyForDeal/(marga*minlot);
            ExtSymbolsSummaries[j][FREE_LOTS]=ExtSymbolsSummaries[j][MAXLOT]-
                                           ExtSymbolsSummaries[j][SUMMLOT]/minlot;
          }
        else
          {
           ExtSymbolsSummaries[j][MAXLOT]=MoneyForDeal/marga;
           ExtSymbolsSummaries[j][FREE_LOTS]=ExtSymbolsSummaries[j][MAXLOT]-
                                           ExtSymbolsSummaries[j][SUMMLOT];
          }
       }
     }
   return ExtSymbolsTotal;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SymbolsIndex(string SymbolName)
  {
   bool found=false;
   int  i;
   string sep=",";                // разделитель в виде символа 
   ushort u_sep;                  // код символа разделителя 
   u_sep=StringGetCharacter(sep,0);
//--- разобьем строку на подстроки 
   ExtSymbolsTotal=StringSplit(InpWorkInstrument,u_sep,ExtSymbols);

//----
   for(i=0; i<ExtSymbolsTotal; i++)
     {

      if(SymbolName==ExtSymbols[i])
        {
         found=true;
         break;
        }
     }
//----
   if(found)
      return(i);
   if(ExtSymbolsTotal>=SYMBOLS_MAX)
      return(-1);

   return(i);
  }
//+------------------------------------------------------------------+
//| Создание отображение надписей                                    |
//+------------------------------------------------------------------+
void RowCreate()
  {
   string name;
   int    i,col,line;
   color cvet1=clrNONE;

//---- header line
   if(ExtLines<0)
     {
      for(col=0; col<8; col++)
        {
         name=" Head_"+string(col);
         LabelCreate(0,prefix+name,0,X+ExtShifts[col],Y+InpExtVertShift,CORNER_LEFT_UPPER,GetHeadName(col),"Gabriola",
                     Inptxtsize+5,InpHeadColor,0,ANCHOR_CENTER,false,false,true,0);
        }
      ExtLines=0;
     }
//----
   int total=Analyze();
   if(total>0)
     {
      line=0;
      for(i=0; i<ExtSymbolsTotal; i++)
        {
         line++;
         //---- add line
         int y_dist=InpExtVertShift*(line);

         if(ExtSymbolsSummaries[i][FREE_LOTS]<0) cvet1=InpNegative; else cvet1=InpPositive;
         for(col=0; col<8; col++)
           {
            name=ExtSymbols[i]+" "+string(line)+"_"+string(col);
            LabelCreate(0,prefix+name,0,X+ExtShifts[col],Y+25+y_dist,CORNER_LEFT_UPPER,ExtCols[col],"Garamond",
                        Inptxtsize,cvet1,0,ANCHOR_CENTER,false,false,true,0);
           }
         //---- set line
         name=ExtSymbols[i]+" "+string(line)+"_0";
         ObjectSetString(0,prefix+name,OBJPROP_TEXT,ExtSymbols[i]);
         name=ExtSymbols[i]+" "+string(line)+"_1";
         ObjectSetString(0,prefix+name,OBJPROP_TEXT,DoubleToStr(ExtSymbolsSummaries[i][DEALS],0));
         name=ExtSymbols[i]+" "+string(line)+"_2";
         ObjectSetString(0,prefix+name,OBJPROP_TEXT,DoubleToStr(ExtSymbolsSummaries[i][SUMMLOT],2));
         name=ExtSymbols[i]+" "+string(line)+"_3";
         ObjectSetString(0,prefix+name,OBJPROP_TEXT,DoubleToStr(ExtSymbolsSummaries[i][MAXLOT],2));
         name=ExtSymbols[i]+" "+string(line)+"_4";
         ObjectSetString(0,prefix+name,OBJPROP_TEXT,DoubleToStr(ExtSymbolsSummaries[i][FREE_LOTS],2));
         name=ExtSymbols[i]+" "+string(line)+"_5";
         ObjectSetString(0,prefix+name,OBJPROP_TEXT,DoubleToStr(ExtSymbolsSummaries[i][BUY_LOTS],2));
         name=ExtSymbols[i]+" "+string(line)+"_6";
         ObjectSetString(0,prefix+name,OBJPROP_TEXT,DoubleToStr(ExtSymbolsSummaries[i][SELL_LOTS],2));
         name=ExtSymbols[i]+" "+string(line)+"_7";
         ObjectSetString(0,prefix+name,OBJPROP_TEXT,DoubleToStr(ExtSymbolsSummaries[i][PROFIT],2));
        }
     }
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   ArrayInitialize(ExtSymbolsSummaries,0.0);
   RowCreate();

   return(rates_total);
  }
//+------------------------------------------------------------------+ 
//| Создает текстовую метку                                          | 
//+------------------------------------------------------------------+ 
bool LabelCreate(const long              chart_ID=0,               // ID графика
                 const string            name="Label",             // имя метки
                 const int               sub_window=0,             // номер подокна
                 const long              x=0,                      // координата по оси X
                 const long              y=0,                      // координата по оси y
                 const ENUM_BASE_CORNER  corner=CORNER_LEFT_UPPER, // угол графика для привязки
                 const string            text="Label",             // текст
                 const string            font="Arial",             // шрифт
                 const int               font_size=10,             // размер шрифта
                 const color             clr=clrNONE,
                 const double            angle=0.0,                // наклон текста
                 const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER, // способ привязки
                 const bool              back=false,               // на заднем плане
                 const bool              selection=false,          // выделить для перемещений
                 const bool              hidden=true,              // скрыт в списке объектов
                 const long              z_order=0)                // приоритет на нажатие мышью
  {
   ResetLastError();
   if(ObjectFind(chart_ID,name)==-1)
     {
      if(!ObjectCreate(chart_ID,name,OBJ_LABEL,sub_window,0,0))
        {
         Print(__FUNCTION__,": не удалось создать текстовую метку! Код ошибки = ",GetLastError());
         return(false);
        }
      ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
      ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
      ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
      ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
      ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
      ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
      ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
      ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
     }
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
   ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
   return(true);
  }
//+------------------------------------------------------------------+
