//+------------------------------------------------------------------+
//|                                               AccountHistory.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
/*
a small utility ea to do daily/weekly/... statistics without counting pips by hand.
You can easy add your/our new eas by name and magic, up to 500 ea.

Just set the ea on any chart and select the desired history period at account history tab.
It is a good idea to set all chart colors to NONE.
If ticks come in then the values are updated only once a minute to save cpu time. 
If you are at weekend and no tick comes in, just change timeperiod of the chart and do a
mouse click in the chart window to get ea update its values.

show_warning = true shows a stop signal if trading is disabled at attached chart.

Do not look at the code, it is quick and dirty, never planned to become so many lines...

Have fun,
bbop

*/
#property copyright "Copyright © 2008 BigBoppa"
#property link      "BigBoppa2de@yahoo.de"

extern bool    hide_privacy    = false;
extern bool    show_warning    = true;
       int     EAs_max         = 500;
       double  cnt_tra          [500];
       double  RealProfit       [500];

//-----------------------------------                   
//-----------------------------------                   


string eaName[50]={"Withdraw",         // reserved, do not change position 0!
                   "Manual Trades",    // reserved, do not change position 1!
                   "Falcon 1",         // reserved, do not change position 2!
                   "Falcon 2",         // reserved, do not change position 3!
                   "Win 2008",
                   "ScalpingGrid",      
                                       // ADD NEW EA NAMEs HERE ...                                                         
                   };
                   
                   
//-----------------------------------                   
//-----------------------------------                   
                   
                   
int magic[50] = {  0,                  // reserved, do not change position 0!
                   0,                  // reserved, do not change position 1!
                   9869500,            // reserved, do not change position 2!
                   9869502,            // reserved, do not change position 3!
                   297638,             // win 2008
                   394608,             // ScalpingGrid
                                       // ADD NEW MAGICs HERE ...            
                   };
                   
//+------------------------------------------------------------------+
//    ... NOTHING TO CHANGE BELOW THIS TEXT ...                
//+------------------------------------------------------------------+

int      x1Pos             = 4;     //name
int      x11Pos            = 500;
int      x2Pos             = 180;   //trades
int      x3Pos             = 245;   //pips
int      x4Pos             = 390;   //profit
int      x5Pos             = 540;   // avg. P/L
int      x7Pos             = 358;

string   Font              = "Courier";   
int      size              = 11;
int      Day_old,n;    
int      Minute_old;   
int      z_old,z_max;     
double   Withdraw;   
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+

int init(){
   deinit();
   Day_old=Day();
   start();
   return(0);
  }
  
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+

int deinit(){
   Minute_old=0;
   ObjectsDeleteAll(0);

   return(0);
   }
   
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+

int start(){

   datetime MinOrderCloseTime=161059999999;
   datetime MaxOrderCloseTime=0;
   int z=0;
   int yPos=4;
   int total = OrdersHistoryTotal();
   double TotalProfit   = 0.0; 
   int    Total_cnt     = 0;
   double Total_pips    = 0.0;
   double Falcon_profit = 0.0;
   color profit=Aqua;
   color loss=Red;   
   
   int Obj_T1_X_pos=258;
   int Obj_T1_Y_pos=70+z_max*12;
   int Obj_T2_X_pos=50;
   int Obj_T2_Y_pos=50+Obj_T1_Y_pos;

   if (!IsTradeAllowed() && IsExpertEnabled() && show_warning){
      SetLabel("Tradisable1","Ä",Obj_T1_X_pos,Obj_T1_Y_pos,"Wingdings 2",100,0,Red); 
      SetLabel("Tradisable2","               TRADING                      DISABLED!",Obj_T2_X_pos,Obj_T2_Y_pos,"Tahoma",16,0,Red); 
      SetLabel("Tradisable3","STOP",Obj_T1_X_pos+20,Obj_T1_Y_pos+43,"Tahoma",24,0,White); 
      }
   else{
      ObjectDelete("Tradisable2");   
      ObjectDelete("Tradisable1");   
      ObjectDelete("Tradisable3");
      }   

     
     
   if (Day()!=Day_old || z_old != z_max)deinit(); //delete old objects at daychange
   z_old    = z_max;
   Day_old  = Day();
   
   if (Minute()==Minute_old)return(0);
   Minute_old=Minute();    // update only once a minute
   
   for (n=0;n<EAs_max;n++){ 
      cnt_tra[n]           = 0;
      RealProfit[n]        = 0.0;
      double DummyProfit   = 0.0;
      double DummyPips     = 0;
      
      for(int i=total-1;i>=0;i--){
         OrderSelect(i, SELECT_BY_POS,MODE_HISTORY);
         MinOrderCloseTime = MathMin(MinOrderCloseTime,OrderCloseTime());
         MaxOrderCloseTime = MathMax(MaxOrderCloseTime,OrderCloseTime());
         if (StringSubstr(OrderSymbol(),0,3)=="JPY" || StringSubstr(OrderSymbol(),3,3)=="JPY")
            int Symbolpoint=100;
         else
            Symbolpoint=10000;
 
         if (OrderMagicNumber()==magic[n] || OrderMagicNumber()==magic[n]+1){   
            
            if (OrderType()==OP_BUY && n>0)
               DummyPips += (OrderClosePrice()-OrderOpenPrice())*Symbolpoint; 
            if (OrderType()==OP_SELL && n>0)
               DummyPips += (OrderOpenPrice()-OrderClosePrice())*Symbolpoint;   
            if (n>1){   
               DummyProfit += OrderProfit()+OrderSwap()+OrderCommission(); 
               cnt_tra[n]++;
               }
            if (OrderClosePrice()-OrderOpenPrice() ==0 && n==0){           // withdraw
               DummyProfit -= OrderProfit()+OrderSwap()+OrderCommission(); 
               cnt_tra[n]++; 
               }              
            if (OrderClosePrice()-OrderOpenPrice() !=0 && n==1){           // manual trade
               DummyProfit += OrderProfit()+OrderSwap()+OrderCommission(); 
               cnt_tra[n]++;
               }

           
            }
         else{ 
            bool MagicIsKnown = false;
            for (int m=0;m<EAs_max;m++){ 
               if (OrderMagicNumber()==magic[m] || OrderMagicNumber()==magic[m]+1){
                  MagicIsKnown = true;
                  break;   // break for m
                  }       // end_if 
               }         // end_for m
            if (!MagicIsKnown){
               for (int p=2;p<EAs_max;p++){ 
                  if (magic[p]==0)break;                       // look for first free field in array magic [p]
                  }  //end_for p
               magic[p] = OrderMagicNumber();                  // store unknown magig in first free field of magic [p]
               eaName[p]= "Magic: "+convert(magic[p],10,0);    // generate "EA-name" for unknown magic
               eaName[p+1]="";                                 
               break;   // break m
               }       // end_if 
            }         // end_else
         }           // end_for i
   
 
      if (eaName[n]=="")                                       // last name compared (including new unnknown names)
         break;                                                // exit to save time, no need to test for 400 empty magics...
         
      if (cnt_tra[n]>0)z++;                                    // if ea did some trades, give it a display-number 
      if (eaName[n]=="Falcon 1" || eaName[n] =="Falcon 2")
         cnt_tra[n]=NormalizeDouble(cnt_tra[n]/3,0);
 
      if (z<10)                                                // some formatting
         string OutText1=" "+(z)+": "+eaName[n];  
      else   
         OutText1=(z)+": "+eaName[n];  
         
      string OutText2=convert(cnt_tra[n],6,0);           
      string OutText3=convert(DummyPips,10,1);              
      string OutText4=convert(DummyProfit,8,2);
      if(hide_privacy && !IsDemo() && DummyProfit>=0)OutText4="  xxxx.xx";
      if(hide_privacy && !IsDemo() && DummyProfit <0)OutText4=" -xxxx.xx";

      if (cnt_tra[n]>0)
         string OutText5=convert(DummyProfit/cnt_tra[n],7,2); 
      if(hide_privacy && !IsDemo() && DummyProfit>=0)OutText5="  xxx.xx";   
      if(hide_privacy && !IsDemo() && DummyProfit <0)OutText5=" -xxx.xx";   

      if (cnt_tra[n]>0) yPos=z*12+38; 
      
      if (DummyPips>0)color Color3=profit;
      else if (DummyPips<0) Color3=loss;
      else Color3=White;
      
      if (DummyProfit>0)color Color4=profit;
      else if (DummyProfit<0) Color4=loss;
      else Color4=White;   
      if (n==0){
         if (DummyProfit>0) Color4=Lime;
         if (DummyProfit<0) Color4=Yellow;
         }
      color Color5=Color4; 
  
      if (cnt_tra[n]>0)SetLabel("EA"+n+"11",OutText1,x1Pos,yPos,Font,size,0,Color5);    // name
      if (cnt_tra[n]>0)SetLabel("EA"+n+"21",OutText2,x2Pos,yPos,Font,size,0,White);     // trades
      if (cnt_tra[n]>0 && n!=0 && eaName[n]!="Falcon 1" && eaName[n] !="Falcon 2") SetLabel("EA"+n+"32",OutText3,x3Pos,yPos,Font,size,0,Color3);   //pips
      if (cnt_tra[n]>0) SetLabel("EA"+n+"42",OutText4,x4Pos,yPos,Font,size,0,Color4);          //profit
      if (cnt_tra[n]>0 && n>0) SetLabel("EA"+n+"52",OutText5,x5Pos,yPos,Font,size,0,Color5);   // avg.P/L

      if (n==0){
         TotalProfit -= DummyProfit;
         Withdraw=DummyProfit;
         }
      else
         TotalProfit += DummyProfit;
         
      if (n==2 || n==3)Falcon_profit += DummyProfit; 
         
      if (n>3 || n==1)Total_cnt += cnt_tra[n]; 
      if (n>3 || n==1)Total_pips += DummyPips; 
      string OutText01="                      Trades         Pips          Profit";
      string OutText02="  average P/L";            
      if (cnt_tra[n]>0)SetLabel("EAx01",OutText01,x1Pos,25,Font,size,0,White);      // headline         
      if (cnt_tra[n]>0)SetLabel("EAx02",OutText02,x11Pos,25,Font,size,0,White);      // headline 
      
      }  // end_for n
   
   if (Total_cnt != 0)double Total_PL = (TotalProfit-Falcon_profit+Withdraw)/Total_cnt;

   
   string OutText6="__________________________________________________________________________________________";
   string OutText7="Overall: ";
   string OutText8=convert(TotalProfit+Withdraw,12,2);  
   string OutText20=convert(Total_pips,10,1); 
   string OutText21=convert(Total_cnt,11,0); 
   string OutText22=convert(Total_PL,12,2);  
   
   if (Total_PL>0)color Color22=profit;
   else if (Total_PL<0) Color22=loss;
   else Color22=White;
   
   if (TotalProfit>0)color Color8=profit;
   else if (TotalProfit<0) Color8=loss;
   else Color8=White;   
   
   if(hide_privacy && !IsDemo() && TotalProfit>=0)OutText8="    xxxxxx.xx";
   if(hide_privacy && !IsDemo() && TotalProfit <0)OutText8="   -xxxxxx.xx";

   if(hide_privacy && !IsDemo() && TotalProfit>=0)OutText22="     xxxxx.xx";
   if(hide_privacy && !IsDemo() && TotalProfit <0)OutText22="    -xxxxx.xx";
   
   if(Total_pips>0)color Color20=profit;
   else if (Total_pips<0) Color20=loss;
   else Color20=White;
   
   if (z>0)SetLabel("EAx61",OutText6,x1Pos,yPos+6,Font,size,0,White);  
   if (z>0)SetLabel("EAx62",OutText6,x1Pos+210,yPos+6,Font,size,0,White);                                    
   if (z>0)SetLabel("EAx71",OutText7,x1Pos,yPos+24,Font,size,0,White);                  
   if (z>0)SetLabel("EAx81",OutText8,x7Pos,yPos+24,Font,size,0,Color8);

   if (z>0)SetLabel("EAx82",OutText20,x3Pos,yPos+23,Font,size,0,Color20);
   else    SetLabel("EAx82","       no trades in history        P/L =",x3Pos,yPos+23,Font,size,0,Color20);
   
   if (z>0)SetLabel("EAx83",OutText21,x2Pos-40,yPos+24,Font,size,0,White);  
   SetLabel("EAx84",OutText22,x5Pos-40,yPos+24,Font,size,0,Color22);  
  
   SetLabel("EAx63",OutText6,x1Pos,7,Font,size,0,White);  
   SetLabel("EAx64",OutText6,x1Pos+210,7,Font,size,0,White); 
   SetLabel("EAx65","Account History",x1Pos,24,Font,size,0,White);                     
   SetLabel("EAx66",OutText6,x1Pos,32,Font,size,0,White);  
   SetLabel("EAx67",OutText6,x1Pos+210,32,Font,size,0,White); 
   
   SetLabel("EAx68",OutText6,x1Pos,yPos+32,Font,size,0,White);  
   SetLabel("EAx69",OutText6,x1Pos+210,yPos+32,Font,size,0,White); 
       
   string AccPrivate = "   "+convert(AccountNumber(),12,0);
   if(hide_privacy) AccPrivate = "";  
   
   if (IsDemo())SetLabel("EAx85"," DEMO",292,1,Font,size,0,Yellow);         
   else         SetLabel("EAx85"," LIVE",292,1,Font,size,0,Lime); 
   
   SetLabel("EAx87"," @ "+AccountCompany()+AccPrivate,332,1,Font,size,0,White);      
   if (z>0)string Dataperiod= StringSubstr(TimeToStr(MinOrderCloseTime),0,10)+"  --->  "+StringSubstr(TimeToStr(MaxOrderCloseTime),0,10);
   else Dataperiod="";
   SetLabel("EAx86",Dataperiod,x1Pos,1,Font,size,0,White); 

   z_max=z;
   
   return(0);
   }
// =========================================================================================== //

// routine to draw the text objects at chart:
void SetLabel(string name,string txt,int x,int y,string font,int size,int angle,color clr){
   int idx=0;
   if(ObjectFind(name) == -1)
       ObjectCreate  (name, OBJ_LABEL, idx, 0, 0);
       
   ObjectSet     (name, OBJPROP_XDISTANCE, x);
   ObjectSet     (name, OBJPROP_YDISTANCE, y);
   ObjectSetText (name, txt, size, font, clr);
   ObjectSet     (name, OBJPROP_CORNER, 4);
   ObjectSet     (name, OBJPROP_ANGLE, angle);
   }   
// =========================================================================================== //

string convert (double Input,int offset, int digis){
   string output="";
   offset-=2;
   int num=offset-digis;

   if (MathAbs(Input)>=10)num=offset-1-digis; 
   if (MathAbs(Input)>=100)num=offset-2-digis; 
   if (MathAbs(Input)>=1000)num=offset-3-digis; 
   if (MathAbs(Input)>=10000)num=offset-4-digis; 
   if (MathAbs(Input)>=100000)num=offset-5-digis; 
   if (MathAbs(Input)>=1000000)num=offset-6-digis; 
   if (MathAbs(Input)>=10000000)num=offset-7-digis; 
   if (MathAbs(Input)>=100000000)num=offset-8-digis; 
   if (MathAbs(Input)>=1000000000)num=offset-9-digis; 
   if (MathAbs(Input)>=10000000000)num=offset-10-digis; 
   if (MathAbs(Input)>=100000000000)num=offset-11-digis; 

   if (Input>=0)num++;
   
   for(int k=0;k<num;k++)
      output=output+" ";
   output=output+DoubleToStr(Input,digis);        
   return(output);  
   }
   
      