//+------------------------------------------------------------------+
//| Equity Chart                                                     |
//| Monitoring balance, equity, margin, profitability and drawdown   |
//+------------------------------------------------------------------+
//| Original idea and code by Xupypr (Igor Korepin)                  |
//| Remake by transcendreamer                                        |
//+------------------------------------------------------------------+

#property copyright "Equity Chart - original by Xupypr - remake by transcendreamer"

#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1 SteelBlue
#property indicator_color2 OrangeRed
#property indicator_color3 SlateGray
#property indicator_color4 ForestGreen
#property indicator_color5 Gray
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 1
#property indicator_width4 1
#property indicator_width5 1

extern bool     Only_Trade=false;
extern string   Only_Magics="";
extern string   Only_Symbols="";
extern string   Only_Comment="";
extern bool     Only_Current=false;
extern bool     Only_Buys=false;
extern bool     Only_Sells=false;

extern bool     Show_Balance=true;
extern bool     Show_Margin=false;
extern bool     Show_Free=false;
extern bool     Show_Zero=false;
extern bool     Show_Info=true;

extern double   Alert_Drawdown=0;
extern double   Max_Drawdown=25;
extern bool     Current_Day=true;
extern datetime Begin_Monitoring=D'2012.01.01 00:00';

extern bool      File_Write=false;
extern datetime  Draw_Begin=D'2012.01.01 00:00';
enum reporting   {month,year,total};
extern reporting Report_Period=month;

extern ENUM_BASE_CORNER Text_Corner=CORNER_LEFT_UPPER;

extern string FX_prefix="";
extern string FX_postfix="";

int      DrawBeginBar,Window;
string   ShortName,Unique;
double   Equity[],Balance[],Margin[],Free[],Zero[];
double   StartBalance,CurrentBalance,MaxPeak,MaxProfit;
double   AbsDrawdown,MaxDrawdown,PctDrawdown,RelDrawdown,Drawdown;
double   RecoveryFactor,ProfitFactor,Profitability,Revenue,TotalProfit,TotalLoss;
datetime saved_time;

datetime OpenTime_Ticket[][2];
int      OpenBar[],CloseBar[],Type[];
string   Instrument[];
double   Lots[],OpenPrice[],ClosePrice[],Commission[],Swap[],CurSwap[],DaySwap[],Profit[];
datetime start_time,finish_time;





//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   if(Only_Magics=="" && Only_Symbols=="" && Only_Comment=="" && !Only_Current && !Only_Buys && !Only_Sells) ShortName="Total";
   else
     {
      if(Only_Magics!="") ShortName=Only_Magics; else ShortName="";
      if(Only_Symbols!="") ShortName=StringConcatenate(ShortName," ",Only_Symbols);
      else if(Only_Current) ShortName=StringConcatenate(ShortName," ",Symbol());
      if(Only_Comment!="") ShortName=StringConcatenate(ShortName," ",Only_Comment);
      if(Only_Sells) Only_Buys=false;
      if(Only_Buys)  ShortName=StringConcatenate(ShortName," Buys");
      if(Only_Sells) ShortName=StringConcatenate(ShortName," Sells");
     }
   if(Only_Trade) ShortName=StringConcatenate(ShortName," Zero");
   
   SetIndexBuffer(0,Equity);
   SetIndexLabel(0,ShortName+" Equity");
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(1,Balance);
   SetIndexLabel(1,ShortName+" Balance");
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(2,Margin);
   SetIndexLabel(2,ShortName+" Margin");
   SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexBuffer(3,Free);
   SetIndexLabel(3,ShortName+" Free");
   SetIndexStyle(3,DRAW_LINE);
   SetIndexBuffer(4,Zero);
   SetIndexLabel(4,ShortName+" Zero");
   SetIndexStyle(4,DRAW_LINE);
   
   ShortName=StringConcatenate(ShortName," Equity");
   if(Show_Balance) ShortName=StringConcatenate(ShortName," Balance");
   if(Show_Margin)  ShortName=StringConcatenate(ShortName," Margin");
   if(Show_Free)    ShortName=StringConcatenate(ShortName," Free");
   
   Unique=(string)ChartID()+(string)ChartWindowFind();
   DrawBeginBar=iBarShift(NULL,0,Draw_Begin);
   IndicatorDigits(2);
   
   return(0);
  }





//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   DeleteAll();
   return(0);
  }





//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
     
   static int anumber=-1;
   static int orders=0;
   static bool first;
   static string minfosymbols;
   string filename,text,date,time;
   double profitloss,spread,lotvalue,result,sum_profit,sum_loss,sum_margin;
   int handle,bar,i,j,start1,total,historytotal,opentotal;
   
   if(Time[0]!=saved_time) first=true;

   if(OrdersTotal()!=orders) { first=true; orders=OrdersTotal(); }

   if(anumber!=AccountNumber())
     {
      DeleteAll();
      IndicatorShortName(Unique);
      Window=WindowFind(Unique);
      IndicatorShortName(ShortName);
      ArrayInitialize(Balance,EMPTY_VALUE);
      ArrayInitialize(Equity,EMPTY_VALUE);
      ArrayInitialize(Margin,EMPTY_VALUE);
      ArrayInitialize(Free,EMPTY_VALUE);
      ArrayInitialize(Zero,EMPTY_VALUE);
      anumber=AccountNumber();
      minfosymbols="";
      first=true;
     }
     
   if(!OrderSelect(0,SELECT_BY_POS,MODE_HISTORY)) return(0);
   
   if(first)
     {
      first=false;
      saved_time=Time[0];
      
      MaxPeak=0.0;
      MaxProfit=0.0;
      AbsDrawdown=0.0;
      MaxDrawdown=0.0;
      RelDrawdown=0.0;
      
      if(Period()>PERIOD_D1)
        {
         Alert("Period must be D1 or lower.");
         return(0);
        }
        
      historytotal=OrdersHistoryTotal();
      opentotal=OrdersTotal();
      total=historytotal+opentotal;
      ArrayResize(OpenTime_Ticket,total);
      
      for(i=0;i<historytotal;i++) if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
        {
         if(FilterOrder())
           {
            OpenTime_Ticket[i][0]=OrderOpenTime();
            OpenTime_Ticket[i][1]=OrderTicket();
            result=OrderProfit()+OrderSwap()+OrderCommission();
            if(OrderType()<2) if(result>0) sum_profit+=result; else sum_loss+=result;
           }
         else
           {
            OpenTime_Ticket[i][0]=EMPTY_VALUE;
            total--;
           }
        }
      
      if(opentotal>0)
        {
         for(i=0;i<opentotal;i++) if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
           {
            if(FilterOrder())
              {
               OpenTime_Ticket[historytotal+i][0]=OrderOpenTime();
               OpenTime_Ticket[historytotal+i][1]=OrderTicket();
               result=OrderProfit()+OrderSwap()+OrderCommission();
               if(result>0) sum_profit+=result; else sum_loss+=result;
              }
            else
              {
               OpenTime_Ticket[historytotal+i][0]=EMPTY_VALUE;
               total--;
              }
           }
        }
            
      if(OrderSelect(0,SELECT_BY_POS,MODE_HISTORY)) start_time=OrderOpenTime();
      if(OrderSelect(historytotal-1,SELECT_BY_POS,MODE_HISTORY)) finish_time=OrderCloseTime();
      
      ArraySort(OpenTime_Ticket);
      ArrayResize(OpenTime_Ticket,total);
      ArrayResize(OpenBar,total);
      ArrayResize(CloseBar,total);
      ArrayResize(Type,total);
      ArrayResize(Lots,total);
      ArrayResize(Instrument,total);
      ArrayResize(OpenPrice,total);
      ArrayResize(ClosePrice,total);
      ArrayResize(Commission,total);
      ArrayResize(Swap,total);
      ArrayResize(CurSwap,total);
      ArrayResize(DaySwap,total);
      ArrayResize(Profit,total);
      
      for(i=0;i<total;i++) if(OrderSelect(OpenTime_Ticket[i][1],SELECT_BY_TICKET)) ReadOrder(i);
      
      if(Type[0]<6 && !Only_Trade)
        {
         Alert("Trading history is not fully loaded");
         return(0);
        }
      
      if(File_Write)
        {
         filename=StringConcatenate(AccountNumber(),"_",Period(),".csv");
         handle=FileOpen(filename,FILE_CSV|FILE_WRITE);
         if(handle<0) Alert("Error #",GetLastError()," while opening data file");
         else if(FileWrite(handle,"Date","Time","Equity","Balance")<=0) Print("Error #",GetLastError()," while writing data file");
        }
        
      start1=0;
      StartBalance=0.0;
      CurrentBalance=0.0;
      spread=MarketInfo(Instrument[j],MODE_POINT)*MarketInfo(Instrument[j],MODE_SPREAD);

      for(i=OpenBar[0];i>=0;i--)
        {
         profitloss=0.0;
         sum_margin=0.0;
         for(j=start1;j<total;j++)
           {
            if(OpenBar[j]<i) break;
            if(CloseBar[start1]>i) start1++;
            if(CloseBar[j]==i && ClosePrice[j]!=0) 
              {
               CurrentBalance+=Swap[j]+Commission[j]+Profit[j];
              }
            else if(OpenBar[j]>=i && CloseBar[j]<=i)
              {
               if(Type[j]>5)
                 {
                  CurrentBalance+=Profit[j];
                  if(i==OpenBar[0]) StartBalance=Profit[j];
                  if(!Only_Trade && i<=DrawBeginBar)
                    {
                     text=StringConcatenate(Instrument[j],": ",DoubleToStr(Profit[j],2)," ",AccountCurrency());
                     LineCreate("Balance "+TimeToStr(OpenTime_Ticket[j][0]),OBJ_VLINE,1,OrangeRed,STYLE_DOT,false,text,Time[i],0);
                    }
                  continue;
                 }
                 
               if(i>DrawBeginBar) continue;
               if(MarketInfo(Instrument[j],MODE_POINT)==0)
                 {
                  if(StringFind(minfosymbols,Instrument[j])==-1)
                    {
                     Alert("Missing symbol in Market Watch: "+Instrument[j]);
                     minfosymbols=StringConcatenate(minfosymbols," ",Instrument[j]);
                    }
                  continue;
                 }
                 
               bar=iBarShift(Instrument[j],0,Time[i]);
               if(TimeDayOfWeek(iTime(Instrument[j],0,bar))!=TimeDayOfWeek(iTime(Instrument[j],0,bar+1)) && OpenBar[j]!=bar)
                 {
                  int pcm=MarketInfo(Instrument[j],MODE_PROFITCALCMODE);
                  switch(pcm)
                    {
                     case 0:
                       {
                        if(TimeDayOfWeek(iTime(Instrument[j],0,bar))==4) CurSwap[j]+=3*DaySwap[j];
                        else CurSwap[j]+=DaySwap[j];
                       }
                     break;
                     case 1:
                       {
                        if(TimeDayOfWeek(iTime(Instrument[j],0,bar))==1) CurSwap[j]+=3*DaySwap[j];
                        else CurSwap[j]+=DaySwap[j];
                       }
                    }
                 }
                 
               lotvalue=ContractValue(Instrument[j],Time[i],Period());
               if(Type[j]==OP_BUY) 
                  {
                  profitloss+=Commission[j]+CurSwap[j]+(iClose(Instrument[j],0,bar)-OpenPrice[j])*Lots[j]*lotvalue;
                  sum_margin+=Lots[j]*MarketInfo(Instrument[j],MODE_MARGINREQUIRED);
                  }
               if(Type[j]==OP_SELL) 
                  {
                  profitloss+=Commission[j]+CurSwap[j]+(OpenPrice[j]-iClose(Instrument[j],0,bar)-spread)*Lots[j]*lotvalue;
                  sum_margin+=Lots[j]*MarketInfo(Instrument[j],MODE_MARGINREQUIRED);
                  }
              }
           }
           
         if(i>DrawBeginBar) continue;
         Equity[i]=NormalizeDouble(CurrentBalance+profitloss,2);
         if(Show_Balance) Balance[i]=NormalizeDouble(CurrentBalance,2);
         if(Show_Info) Drawdown(CurrentBalance+profitloss);
         if(Show_Margin) Margin[i]=NormalizeDouble(sum_margin,2);
         if(Show_Free) Free[i]=NormalizeDouble(Equity[i]-sum_margin,2);
         if(Show_Zero) Zero[i]=0;
         
         if(File_Write && handle>0)
           {
            date=TimeToStr(Time[i],TIME_DATE);
            time=TimeToStr(Time[i],TIME_MINUTES);
            if(FileWrite(handle,date,time,CurrentBalance+profitloss,CurrentBalance)<=0) 
               Print("Error #",GetLastError()," while writing data file");
           }
        }
        
      ArrayResize(OpenTime_Ticket,opentotal);
      if(opentotal>0) for(i=0;i<opentotal;i++) if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) OpenTime_Ticket[i][1]=OrderTicket();
      if(File_Write && handle>0) FileClose(handle);
     }
     
   if(true)
     {
      if(Only_Magics=="" && Only_Symbols=="" && Only_Comment=="" && !Only_Current && !Only_Buys && !Only_Sells && !Only_Trade)
        {
         Equity[0]=AccountEquity();
         if(Show_Balance) Balance[0]=AccountBalance();
         if(Show_Margin) Margin[0]=AccountMargin();
         if(Show_Free) Free[0]=AccountFreeMargin();
         if(Show_Info) Drawdown(AccountEquity());
         if(opentotal>0) finish_time=TimeCurrent();
        }
      else
        {
         opentotal=ArraySize(OpenTime_Ticket);
         if(opentotal>0)
           {
            for(i=0;i<opentotal;i++)
              {
               if(!OrderSelect(OpenTime_Ticket[i][1],SELECT_BY_TICKET)) continue;
               if(OrderCloseTime()==0) continue;
               if(!FilterOrder()) continue;
               CurrentBalance+=OrderProfit()+OrderSwap()+OrderCommission();
              }
           }
         profitloss=0.0;
         sum_margin=0.0;
         opentotal=OrdersTotal();
         if(opentotal>0)
           {
            for(i=0;i<opentotal;i++)
              {
               if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
               if(!FilterOrder()) continue;
               profitloss+=OrderProfit()+OrderSwap()+OrderCommission();
               sum_margin+=Lots[i]*MarketInfo(Instrument[i],MODE_MARGINREQUIRED);
              }
           }
         Equity[0]=NormalizeDouble(CurrentBalance+profitloss,2);
         if(Show_Balance) Balance[0]=NormalizeDouble(CurrentBalance,2);
         if(Show_Info) Drawdown(CurrentBalance+profitloss);
         if(Show_Margin) Margin[0]=NormalizeDouble(sum_margin,2);
         if(Show_Free) Free[0]=NormalizeDouble(Equity[0]-sum_margin,2);
         if(Show_Zero) Zero[0]=0;

         ArrayResize(OpenTime_Ticket,opentotal);
         if(opentotal>0) for(i=0;i<opentotal;i++) if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) OpenTime_Ticket[i][1]=OrderTicket();
         if(opentotal>0) finish_time=TimeCurrent();
        }
     }
   
   LineCreate("Equity Level",OBJ_HLINE,1,SteelBlue,STYLE_DOT,false,"",0,Equity[0]);
   TotalProfit=sum_profit; TotalLoss=sum_loss;
   if(Show_Info) ShowStatistics();
   if(Alert_Drawdown>0) AlertDrawdown();

   return(0);
  }





//+------------------------------------------------------------------+
//| Trading statistics                                               |
//+------------------------------------------------------------------+
void ShowStatistics()
   {
      if(TotalLoss<0) ProfitFactor=-(TotalProfit)/(TotalLoss);
      string text=StringConcatenate(": ",DoubleToStr(ProfitFactor,2));
      LabelCreate("Profit Factor",text,80);
      
      if(MaxDrawdown>0) RecoveryFactor=(Equity[0]-StartBalance)/MaxDrawdown;
      text=StringConcatenate(": ",DoubleToStr(RecoveryFactor,2));
      LabelCreate("Recovery Factor",text,60);

      if(MaxPeak>0) PctDrawdown=100*MaxDrawdown/MaxPeak;
      if(Only_Trade) text=StringConcatenate(": ", DoubleToStr(MaxDrawdown,2), " ", AccountCurrency());
      else text=StringConcatenate(": ", DoubleToStr(MaxDrawdown,2), " ", AccountCurrency()," (",DoubleToStr(PctDrawdown,2),"%)");
      LabelCreate("Max Drawdown",text,40);

      double periods=(double)(finish_time-start_time)/60/60/24;
      if(Report_Period==month) periods/=30;
      if(Report_Period==year) periods/=360;
      if(Report_Period==total) periods=1;
      Revenue=(Equity[0]-StartBalance)/periods;
      if(StartBalance>0) Profitability=100*(Equity[0]-StartBalance)/StartBalance/periods;
      if(Only_Trade) text=StringConcatenate(": ", DoubleToStr(Revenue,2), " ", AccountCurrency());
      else text=StringConcatenate(": ", DoubleToStr(Revenue,2), " ", AccountCurrency(), " (", DoubleToStr(Profitability,2),"%)");
      if(Report_Period==month) text+=" / month";
      if(Report_Period==year) text+=" / year";
      if(Report_Period==total) text+=" / total";
      LabelCreate("Profitability",text,20);
   }





//+------------------------------------------------------------------+
//| Text label                                                       |
//+------------------------------------------------------------------+
void LabelCreate(string name,string str,int y)
  {
   string objectname=StringConcatenate(name," ",Unique);
   if(ObjectFind(objectname)==-1)
     {
      ObjectCreate(objectname,OBJ_LABEL,Window,0,0);
      ObjectSet(objectname,OBJPROP_XDISTANCE,10);
      ObjectSet(objectname,OBJPROP_YDISTANCE,y);
      ObjectSet(objectname,OBJPROP_COLOR,indicator_color1);
      ObjectSet(objectname,OBJPROP_CORNER,Text_Corner);
     }
   ObjectSetText(objectname,name+str);
  }





//+------------------------------------------------------------------+
//| Trendline/vertical/horizontal                                    |
//+------------------------------------------------------------------+
void LineCreate(string name, int type, int width, color clr, int style, bool ray, string str,
datetime time1, double price1, datetime time2=0, double price2=0)
  {
   string objectname=StringConcatenate(name," ",Unique);
   if(ObjectFind(objectname)==-1)
     {
      ObjectCreate(objectname,type,Window,time1,price1,time2,price2);
      ObjectSet(objectname,OBJPROP_WIDTH,width);
      ObjectSet(objectname,OBJPROP_RAY,ray);
     }
   ObjectSetText(objectname,str);
   ObjectSet(objectname,OBJPROP_COLOR,clr);
   ObjectSet(objectname,OBJPROP_TIME1,time1);
   ObjectSet(objectname,OBJPROP_PRICE1,price1);
   ObjectSet(objectname,OBJPROP_TIME2,time2);
   ObjectSet(objectname,OBJPROP_PRICE2,price2);
   ObjectSet(objectname,OBJPROP_STYLE,style);
  }





//+------------------------------------------------------------------+
//| Objects deletion                                                 |
//+------------------------------------------------------------------+
void DeleteAll()
  {
   int total=ObjectsTotal()-1;
   for(int i=total;i>=0;i--)
     {
      string name=ObjectName(i);
      if(StringFind(name,Unique)!=-1) ObjectDelete(name);
     }
  }





//+------------------------------------------------------------------+
//| Orders processing                                                |
//+------------------------------------------------------------------+
void ReadOrder(int n)
  {
   OpenBar[n]=iBarShift(NULL,0,OrderOpenTime());
   Type[n]=OrderType();
   if(OrderType()>5) Instrument[n]=OrderComment();
   else Instrument[n]=OrderSymbol();
   Lots[n]=OrderLots();
   OpenPrice[n]=OrderOpenPrice();
   if(OrderCloseTime()!=0)
     {
      CloseBar[n]=iBarShift(NULL,0,OrderCloseTime());
      ClosePrice[n]=OrderClosePrice();
     }
   else
     {
      CloseBar[n]=0;
      ClosePrice[n]=0.0;
     }
   Commission[n]=OrderCommission();
   Swap[n]=OrderSwap();
   Profit[n]=OrderProfit();
   if(OrderType()>5 && Only_Trade) Profit[n]=0.0;
   CurSwap[n]=0.0;
   int swapdays=0;
   for(int b=OpenBar[n]-1;b>=CloseBar[n];b--)
     {
      if(TimeDayOfWeek(iTime(NULL,0,b))!=TimeDayOfWeek(iTime(NULL,0,b+1)))
        {
         int pcm=MarketInfo(Instrument[n],MODE_PROFITCALCMODE);
         switch(pcm)
           {
            case 0:
              {
               if(TimeDayOfWeek(iTime(NULL,0,b))==4) swapdays+=3;
               else swapdays++;
              }
            break;
            case 1:
              {
               if(TimeDayOfWeek(iTime(NULL,0,b))==1) swapdays+=3;
               else swapdays++;
              }
           }
        }
     }
   if(swapdays>0) DaySwap[n]=Swap[n]/swapdays; else DaySwap[n]=0.0;
   if(Lots[n]==0)
     {
      string ticket=StringSubstr(OrderComment(),StringFind(OrderComment(),"#")+1);
      if(OrderSelect(StrToInteger(ticket),SELECT_BY_TICKET,MODE_HISTORY)) Lots[n]=OrderLots();
     }
  }





//+------------------------------------------------------------------+
//| Order filter                                                     |
//+------------------------------------------------------------------+
bool FilterOrder()
  {
   if(OrderType()>5) return(true);
   if(OrderType()>1) return(false);
   if(Only_Magics!="" && StringFind(Only_Magics,DoubleToStr(OrderMagicNumber(),0))==-1) return(false);
   if(Only_Symbols!="" && StringFind(Only_Symbols,OrderSymbol())==-1) return(false);
   else if(Only_Current && OrderSymbol()!=Symbol()) return(false);
   if(Only_Comment!="" && StringFind(OrderComment(),Only_Comment)==-1) return(false);
   if(Only_Buys && OrderType()!=OP_BUY) return(false);
   if(Only_Sells && OrderType()!=OP_SELL) return(false);
   return(true);
  }





//+------------------------------------------------------------------+
//| Drawdown calculation                                             |
//+------------------------------------------------------------------+
void Drawdown(double equity)
  {
   double relative;
   if(AbsDrawdown<StartBalance-equity) AbsDrawdown=StartBalance-equity;
   if(equity>MaxProfit) MaxProfit=equity;
   if(MaxDrawdown<MaxProfit-equity)
     {
      MaxDrawdown=MaxProfit-equity;
      MaxPeak=MaxProfit;
      if(MaxPeak>0)
        {
         relative=100*MaxDrawdown/MaxPeak;
         if(RelDrawdown<relative)
           {
            RelDrawdown=relative;
            Drawdown=MaxDrawdown;
           }
        }
     }
  }





//+------------------------------------------------------------------+
//| Drawdown alert                                                   |
//+------------------------------------------------------------------+
void AlertDrawdown()
  {
   static int day;
   static bool first=true;
   static double maxpeak,maxprofit,maxdrawdown,reldrawdown,drawdown,balanceDD,maxDD;
   static datetime time,timemaxprofit;
   int bar=0;
   double high,relative,level,curdrawdown;
   datetime timehigh,timelow;
   string drawdownstr,text;
   color clr;

   if(first)
     {
      first=false;
      day=Day();
      if(Current_Day) time=StrToTime(TimeToStr(Time[0],TIME_DATE));
      else time=Begin_Monitoring;
      if(time<Draw_Begin) time=Draw_Begin;
      if(time<OpenTime_Ticket[0][0]) time=OpenTime_Ticket[0][0];
      bar=iBarShift(NULL,0,time);
      maxprofit=0.0;
      maxdrawdown=0.0;
      reldrawdown=0.0;
      balanceDD=0.0;
      maxDD=Alert_Drawdown;
     }
   else 
      if(Current_Day && Day()!=day) 
         first=true;
   
   for(int i=bar; i>=0; i--)
     {
      if(Equity[i]<0) return;
      high=Equity[i];
      if(high>maxprofit)
        {
         timemaxprofit=Time[i];
         maxprofit=high;
         maxdrawdown=0.0;
         reldrawdown=0.0;
         maxDD=Alert_Drawdown;
        }
      if(Show_Balance && balanceDD<Balance[i]-Equity[i]) balanceDD=Balance[i]-Equity[i];
      if(maxdrawdown<maxprofit-Equity[i])
        {
         maxdrawdown=maxprofit-Equity[i];
         maxpeak=maxprofit;
         timehigh=timemaxprofit;
         if(maxpeak>0)
           {
            relative=NormalizeDouble(100*maxdrawdown/maxpeak,1);
            if(reldrawdown<relative)
              {
               reldrawdown=relative;
               drawdown=maxdrawdown;
               timelow=Time[i];
              }
           }
        }
     }
   
   if(ObjectFind("up")>0)
     {
      if(ObjectGet("up",OBJPROP_PRICE1)<Equity[0])
        {
         Alert("Equity is higher than maximal level");
         ObjectSet("up",OBJPROP_PRICE1,Equity[0]);
        }
     }
   
   if(ObjectFind("down")>0)
     {
      if(ObjectGet("down",OBJPROP_PRICE1)>Equity[0])
        {
         Alert("Equity is lower than minimal level");
         ObjectSet("down",OBJPROP_PRICE1,Equity[0]);
        }
     }
   
   if(reldrawdown>maxDD)
     {
      maxDD=reldrawdown;
      if(maxDD>Max_Drawdown)
        {
         text=StringConcatenate("Drawdown limit exceeded by: ",DoubleToStr(maxDD-Alert_Drawdown,1),"%\n");
         text=StringConcatenate(text,"Drawdown limit: ",DoubleToStr(Max_Drawdown,1),"%\n");
        }
      else
        {
         text=StringConcatenate("Drawdown signal exceeded by: ",DoubleToStr(maxDD-Alert_Drawdown,1),"%\n");
         text=StringConcatenate(text,"Drawdown signal: ",DoubleToStr(Alert_Drawdown,1),"%\n");
        }
      drawdownstr=StringConcatenate(DoubleToStr(reldrawdown,1),"% (",DoubleToStr(drawdown,2)," ",AccountCurrency(),")");
      text=StringConcatenate(text,"Drawdown for the period: ",drawdownstr,"\n");
      if(balanceDD>0) text=StringConcatenate(text,"Balance drawdown: ",DoubleToStr(balanceDD,2)," ",AccountCurrency(),"\n");
      text=StringConcatenate(text,"Indicator name: ",ShortName);
      Alert(text);
      if(maxDD>Max_Drawdown) clr=Red;
      else clr=DarkOrange;
      LineCreate("Drawdown Line",OBJ_TREND,2,clr,STYLE_DOT,false,"       "+drawdownstr,timehigh,maxpeak,timelow,maxpeak-drawdown);
     }
     
   LineCreate("Begin Monitoring",OBJ_VLINE,1,SlateGray,STYLE_DOT,false,"Begin Monitoring",time,0);
   level=NormalizeDouble(maxprofit,2);
   LineCreate("Max Profit",OBJ_TREND,1,DodgerBlue,STYLE_DOT,false,"Max Profit",timemaxprofit,level,Time[0],level);
   level=NormalizeDouble(maxprofit*(1-Alert_Drawdown/100),2);
   LineCreate("Alert Drawdown",OBJ_TREND,1,DarkOrange,STYLE_DOT,false,"Alert Drawdown "+DoubleToStr(Alert_Drawdown,1)+"%",timemaxprofit,level,Time[0],level);
   level=NormalizeDouble(maxprofit*(1-Max_Drawdown/100),2);
   LineCreate("Max Drawdown",OBJ_TREND,1,Red,STYLE_DOT,false,"Max Drawdown "+DoubleToStr(Max_Drawdown,1)+"%",timemaxprofit,level,Time[0],level);
   
   if(Show_Info)
     {
      curdrawdown=maxprofit-Equity[0];
      text=StringConcatenate(": ",DoubleToStr(curdrawdown,2)," ",AccountCurrency()," (",DoubleToStr(100*curdrawdown/maxprofit,2),"%)");
      LabelCreate("Current Drawdown",text,100);
     }
  }





//+------------------------------------------------------------------+
//| Contract value calculation                                       |
//+------------------------------------------------------------------+
double ContractValue(string symbol, datetime time, int period)
{

int shift;
double price;
double value=0;
string Chart_Currency=AccountCurrency();
int type=(int)MarketInfo(symbol,MODE_PROFITCALCMODE);
string quote=SymbolInfoString(symbol,SYMBOL_CURRENCY_PROFIT);
string base=SymbolInfoString(symbol,SYMBOL_CURRENCY_BASE);
string direct=FX_prefix+quote+"USD"+FX_postfix;
string indirect=FX_prefix+"USD"+quote+FX_postfix;

switch(type)
{

case 0:
   value=MarketInfo(symbol,MODE_LOTSIZE);
   if(quote=="USD") break;
   if(base=="USD")
      {
      shift=iBarShift(symbol,period,time);
      price=iClose(symbol,period,shift);
      if(price>0) value/=price;
      }
   else
      {
      if(MarketInfo(direct,MODE_POINT)!=0)
         {
         shift=iBarShift(direct,period,time);
         price=iClose(direct,period,shift);
         if(price>0) value*=price;
         }
      else
         {
         shift=iBarShift(indirect,period,time);
         price=iClose(indirect,period,shift);
         if(price>0) value/=price;
         }
      }
   break;

case 1: 
   value=MarketInfo(symbol,MODE_LOTSIZE); 
   if(quote=="USD") break;
   else
      {
      if(MarketInfo(direct,MODE_POINT)!=0)
         {
         shift=iBarShift(direct,period,time);
         price=iClose(direct,period,shift);
         if(price>0) value*=price;
         }
      else
         {
         shift=iBarShift(indirect,period,time);
         price=iClose(indirect,period,shift);
         if(price>0) value/=price;
         }
      }
   break;

case 2: 
   value=MarketInfo(symbol,MODE_LOTSIZE); 
   if(quote=="USD") break;
   else
      {
      if(MarketInfo(direct,MODE_POINT)!=0)
         {
         shift=iBarShift(direct,period,time);
         price=iClose(direct,period,shift);
         if(price>0) value*=price;
         }
      else
         {
         shift=iBarShift(indirect,period,time);
         price=iClose(indirect,period,shift);
         if(price>0) value/=price;
         }
      }
   break;

}

direct=FX_prefix+Chart_Currency+"USD"+FX_postfix;
indirect=FX_prefix+"USD"+Chart_Currency+FX_postfix;
if(Chart_Currency!="USD")
   {
   if(MarketInfo(direct,MODE_POINT)!=0)
      {
      shift=iBarShift(direct,period,time);
      price=iClose(direct,period,shift);
      if(price>0) value/=price;
      }
   else
      {
      shift=iBarShift(indirect,period,time);
      price=iClose(indirect,period,shift);
      if(price>0) value*=price;
      }
   }

return(value);

}

