Equity_v7





//+------------------------------------------------------------------+
//|                                                    Equity_v7.mq4 |
//|                                         Copyright © 2008, Xupypr |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, Xupypr"

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 OrangeRed
#property indicator_color2 DodgerBlue
#property indicator_color3 SlateGray
#property indicator_color4 ForestGreen
#property indicator_width1 2
#property indicator_width2 1
#property indicator_width3 1
#property indicator_width4 1

extern datetime Date_Begin=D'2000.01.01 00:00'; // Íà÷àëüíàÿ äàòà îòðèñîâêè èíäèêàòîðà ïðè íóëåâîì áàëàíñå
extern bool     Zero_Balance=false; // Ó÷èòûâàòü òîëüêî òîðãîâûå îðäåðà èñêëþ÷àÿ ïîïîëíåíèå/ñíÿòèå ñðåäñòâ
extern string   Only_Magics="";     // Ó÷èòûâàòü îðäåðà òîëüêî ñ óêàçàííûìè ìàãè÷åñêèìè íîìåðàìè (÷åðåç ëþáîé ðàçäåëèòåëü)
extern string   Only_Symbols="";    // Ó÷èòûâàòü òîëüêî óêàçàííûå èíñòðóìåíòû (÷åðåç ëþáîé ðàçäåëèòåëü)
extern bool     Only_Current=false; // Ó÷èòûâàòü òîëüêî òåêóùèé èíñòðóìåíò
extern bool     Show_Balance=true; // Îòîáðàæàòü áàëàíñ
extern bool     Show_Equity=true;  // Îòîáðàæàòü ñðåäñòâà
extern bool     Show_Margin=false; // Îòîáðàæàòü çàëîã (òîëüêî â ðåæèìå ðåàëüíîãî âðåìåíè)
extern bool     Show_Free=false;   // Îòîáðàæàòü ñâîáîäíûå ñðåäñòâà (òîëüêî â ðåæèìå ðåàëüíîãî âðåìåíè)
extern bool     Show_Info=false;   // Îòîáðàæàòü äîïîëíèòåëüíóþ èíôîðìàöèþ

int    ANumber,Window;
double Balance[],Equity[],Margin[],Free[];
double CurrentBalance,StartBalance,MaxProfit,Drawdown,MaxPeak,RecoveryFactor;
string Shortname;
datetime TimeBar;

datetime OpenTime_Ticket[][2]; // âðåìÿ îòêðûòèÿ è íîìåð òèêåòà
int      OpenBar[];            // íîìåð áàðà îòêðûòèÿ
int      CloseBar[];           // íîìåð áàðà çàêðûòèÿ
int      Type[];               // òèï îïåðàöèè
string   Instrument[];         // èíñòðóìåíò
double   Lots[];               // êîëè÷åñòâî ëîòîâ
double   OpenPrice[];          // öåíà îòêðûòèÿ
double   ClosePrice[];         // öåíà çàêðûòèÿ
double   Commission[];         // êîìèññèÿ
double   Swap[];               // íàêîïëåííûé ñâîï
double   CurSwap[];            // òåêóùèé ñâîï
double   DaySwap[];            // äíåâíîé ñâîï
double   Profit[];             // ÷èñòàÿ ïðèáûëü
double   Magic[];              // ìàãè÷åñêèé íîìåð

//+----------------------------------------------------------------------------+
//|  Custom indicator initialization function                                  |
//+----------------------------------------------------------------------------+
int init()
{
 if (Only_Magics=="" && Only_Symbols=="" && !Only_Current) Shortname="Total";
 else
 {
  if (Only_Magics!="") Shortname=Only_Magics; else Shortname="0";
  if (Only_Symbols!="") Shortname=StringConcatenate(Shortname," ",Only_Symbols);
  else if (Only_Current) Shortname=StringConcatenate(Shortname," ",Symbol());
 }
 SetIndexBuffer(0,Balance);
 SetIndexLabel(0,Shortname+" Balance");
 SetIndexStyle(0,DRAW_LINE);
 SetIndexBuffer(1,Equity);
 SetIndexLabel(1,Shortname+" Equity");
 SetIndexStyle(1,DRAW_LINE);
 SetIndexBuffer(2,Margin);
 SetIndexLabel(2,Shortname+" Margin");
 SetIndexStyle(2,DRAW_LINE);
 SetIndexBuffer(3,Free);
 SetIndexLabel(3,Shortname+" Free");
 SetIndexStyle(3,DRAW_LINE);
 if (Show_Balance) Shortname=StringConcatenate(Shortname," Balance");
 if (Show_Equity)  Shortname=StringConcatenate(Shortname," Equity");
 if (Show_Margin)  Shortname=StringConcatenate(Shortname," Margin");
 if (Show_Free)    Shortname=StringConcatenate(Shortname," Free");
 IndicatorShortName(Shortname);
 IndicatorDigits(2);
 return(0);
}
//+----------------------------------------------------------------------------+
//|  Custom indicator deinitialization function                                |
//+----------------------------------------------------------------------------+
int deinit()
{
 ObjectsDeleteAll(Window);
 return(0);
}
//+----------------------------------------------------------------------------+
//|  Custom indicator iteration function                                       |
//+----------------------------------------------------------------------------+
int start()
{
 string name,text;
 static string symbols="";
 double profitloss,spread,lotsize;
 int bar,i,j,start,total,historytotal,opentotal;
 //int tick=GetTickCount();

 if (ANumber!=AccountNumber())
 {
  ArrayInitialize(Balance,EMPTY_VALUE);
  ArrayInitialize(Equity,EMPTY_VALUE);
  ArrayInitialize(Margin,EMPTY_VALUE);
  ArrayInitialize(Free,EMPTY_VALUE);
  ObjectsDeleteAll(Window);
  ANumber=AccountNumber();
  symbols="";
  TimeBar=0;
 }
 if (!IsConnected())
 {
  Print("Ñâÿçü ñ ñåðâåðîì îòñóòñòâóåò èëè ïðåðâàíà");
  return(0);
 }
 if (!OrderSelect(0,SELECT_BY_POS,MODE_HISTORY)) return(0);
 Window=WindowFind(Shortname);
 if (Time[0]!=TimeBar)
 {
  TimeBar=Time[0];
  if (Period()>PERIOD_D1)
  {
   Alert("Ïåðèîä íå ìîæåò áûòü áîëüøå D1"); 
   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 (Select())
   {
    OpenTime_Ticket[i][0]=OrderOpenTime();
    OpenTime_Ticket[i][1]=OrderTicket();
   }
   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 (Select())
    {
     OpenTime_Ticket[historytotal+i][0]=OrderOpenTime();
     OpenTime_Ticket[historytotal+i][1]=OrderTicket();
    }
    else
    {
     OpenTime_Ticket[historytotal+i][0]=EMPTY_VALUE;
     total--;
    }
   }
  }
  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);
  ArrayResize(Magic,total);
  for (i=0;i<total;i++) if (OrderSelect(OpenTime_Ticket[i][1],SELECT_BY_TICKET)) ReadDeals(i);
  if (Type[0]<6 && !Zero_Balance)
  {
   Alert("Èñòîðèÿ ñäåëîê çàãðóæåíà íå ïîëíîñòüþ");
   return(0);
  }
  start=0;
  CurrentBalance=0.0;
  StartBalance=0.0;
  MaxProfit=0.0;
  Drawdown=0.0;
  MaxPeak=0.0;
  for (i=OpenBar[0];i>=0;i--)
  {
   if (Zero_Balance && i>iBarShift(NULL,0,Date_Begin)) continue;
   profitloss=0.0;
   for (j=start;j<total;j++)
   {
    if (OpenBar[j]<i) break;
    if (CloseBar[start]>i) start++;
    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];
      StartBalance+=Profit[j];
      name=StringConcatenate("Time: ",TimeToStr(Time[i]));
      if (ObjectFind(name)==-1) ObjectCreate(name,OBJ_VLINE,Window,Time[i],0);
      ObjectSetText(name,StringConcatenate(Instrument[j],": ",DoubleToStr(Profit[j],2)));
      ObjectSet(name,OBJPROP_TIME1,Time[i]);
      ObjectSet(name,OBJPROP_COLOR,OrangeRed);
      ObjectSet(name,OBJPROP_WIDTH,2);
      continue;
     }
     if (MarketInfo(Instrument[j],MODE_POINT)==0)
     {
      if (StringFind(symbols,Instrument[j])==-1)
      {
       Alert("Â îáçîðå ðûíêà íå õâàòàåò "+Instrument[j]);
       symbols=StringConcatenate(symbols," ",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)
     {
      switch (MarketInfo(Instrument[j],MODE_PROFITCALCMODE))
      {
       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];
       }
      }
     }
     lotsize=LotSize(Instrument[j],Time[i]);
     if (Type[j]==OP_BUY) profitloss+=Commission[j]+CurSwap[j]+(iClose(Instrument[j],0,bar)-OpenPrice[j])*Lots[j]*lotsize;
     else
     {
      spread=MarketInfo(Instrument[j],MODE_POINT)*MarketInfo(Instrument[j],MODE_SPREAD);
      profitloss+=Commission[j]+CurSwap[j]+(OpenPrice[j]-iClose(Instrument[j],0,bar)-spread)*Lots[j]*lotsize;
     }
    }
   }
   if (Show_Balance) Balance[i]=NormalizeDouble(CurrentBalance,2);
   if (Show_Equity)  Equity[i]=NormalizeDouble(CurrentBalance+profitloss,2);
   if (Show_Info)    Information(i,CurrentBalance+profitloss);
  }
  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();
  }
 }
 else
 {
  if (Only_Magics=="" && Only_Symbols=="" && !Only_Current && !Zero_Balance)
  {
   if (Show_Balance) Balance[0]=AccountBalance();
   if (Show_Equity)  Equity[0]=AccountEquity();
   if (Show_Margin)  Margin[0]=AccountMargin();
   if (Show_Free)    Free[0]=AccountFreeMargin();
   if (Show_Info)    Information(0,AccountEquity());
  }
  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;
     else if (Select()) CurrentBalance+=OrderCommission()+OrderSwap()+OrderProfit();
    }
   }
   profitloss=0.0;
   opentotal=OrdersTotal();
   if (opentotal>0)
   {
    for (i=0;i<opentotal;i++)
    {
     if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
     if (Select()) profitloss+=OrderCommission()+OrderSwap()+OrderProfit();
    }
   }
   if (Show_Balance) Balance[0]=NormalizeDouble(CurrentBalance,2);
   if (Show_Equity)  Equity[0]=NormalizeDouble(CurrentBalance+profitloss,2);
   if (Show_Info)    Information(0,CurrentBalance+profitloss);
   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 (Show_Info)
 {
  name="maximal_drawdown";
  if (ObjectFind(name)==-1) ObjectCreate(name,OBJ_LABEL,Window,0,0);
  text=StringConcatenate("Maximal Drawdown: ",DoubleToStr(Drawdown,2)," (",DoubleToStr(100*Drawdown/MaxPeak,2),"%)");
  ObjectSetText(name,text);
  ObjectSet(name,OBJPROP_XDISTANCE,10);
  ObjectSet(name,OBJPROP_YDISTANCE,10);
  ObjectSet(name,OBJPROP_CORNER,1);
  ObjectSet(name,OBJPROP_COLOR,Silver);
  name="recovery_factor";
  if (ObjectFind(name)==-1) ObjectCreate(name,OBJ_LABEL,Window,0,0);
  text=StringConcatenate("Recovery Factor: ",DoubleToStr(RecoveryFactor,2));
  ObjectSetText(name,text);
  ObjectSet(name,OBJPROP_XDISTANCE,10);
  ObjectSet(name,OBJPROP_YDISTANCE,30);
  ObjectSet(name,OBJPROP_CORNER,1);
  ObjectSet(name,OBJPROP_COLOR,Silver);
 }
 //Print("Calculating - ",GetTickCount()-tick," ms");
 return(0);
}
//+----------------------------------------------------------------------------+
//|  ×òåíèå ñäåëîê                                                             |
//+----------------------------------------------------------------------------+
void ReadDeals(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 && Zero_Balance) 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)))
  {
   switch (MarketInfo(Instrument[n],MODE_PROFITCALCMODE))
   {
    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;
 Magic[n]=OrderMagicNumber();
}
//+----------------------------------------------------------------------------+
//|  Ðàñ÷¸ò ìàêñèìàëüíîé ïðîñàäêè                                             |
//+----------------------------------------------------------------------------+
void Information(int bar, double equity)
{
 if (MaxProfit<equity) MaxProfit=equity;
 if (Drawdown<(MaxProfit-equity))
 {
  Drawdown=MaxProfit-equity;
  MaxPeak=MaxProfit;
 } 
 if (Drawdown>0 && bar==0) RecoveryFactor=(equity-StartBalance)/Drawdown;
}
//+----------------------------------------------------------------------------+
//|  Îïðåäåëåíèå ðàçìåðà êîíòðàêòà                                             |
//+----------------------------------------------------------------------------+
double LotSize(string symbol, datetime tbar)
{
 double size;
 string BQ,currency=AccountCurrency();
 switch (MarketInfo(symbol,MODE_PROFITCALCMODE))
 {
  case 0:
  {
   int sbar=iBarShift(symbol,0,tbar);
   size=MarketInfo(symbol,MODE_LOTSIZE);
   if (StringSubstr(symbol,3,3)=="USD") break;
   if (StringSubstr(symbol,0,3)=="USD") size=size/iClose(symbol,0,sbar);
   else
   {
    BQ=StringSubstr(symbol,0,3)+"USD";
    if (iClose(BQ,0,0)==0) BQ="USD"+StringSubstr(symbol,0,3);
    if (iClose(BQ,0,0)==0) break;
    int BQbar=iBarShift(BQ,0,tbar);
    if (StringSubstr(BQ,0,3)=="USD") size=size/iClose(BQ,0,BQbar)/iClose(symbol,0,sbar);
    else size=size*iClose(BQ,0,BQbar)/iClose(symbol,0,sbar);
   }
  } break;
  case 1: size=MarketInfo(symbol,MODE_LOTSIZE); break;
  case 2: size=MarketInfo(symbol,MODE_TICKVALUE)/MarketInfo(symbol,MODE_TICKSIZE);
 }
 if (currency!="USD")
 {
  BQ=currency+"USD";
  if (iClose(BQ,0,0)==0)
  {
   BQ="USD"+currency;
   size*=iClose(BQ,0,iBarShift(BQ,0,tbar));
  }
  else size/=iClose(BQ,0,iBarShift(BQ,0,tbar));
 }
 return(size);
}
//+----------------------------------------------------------------------------+
//|  Âûáîð îðäåðà ïî êðèòåðèÿì                                                 |
//+----------------------------------------------------------------------------+
bool Select()
{
 if (OrderType()>5) return(true);
 if (OrderType()>1) return(false);
 if (Only_Magics!="")
 {
  if (StringFind(Only_Magics,DoubleToStr(OrderMagicNumber(),0))==-1) return(false);
 }
 if (Only_Symbols!="")
 {
  if (StringFind(Only_Symbols,OrderSymbol())==-1) return(false);
 }
 else if (Only_Current && OrderSymbol()!=Symbol()) return(false);
 return(true);
}
//+----------------------------------------------------------------------------+



Sample





Analysis



Market Information Used:

Series array that contains open time of each bar
Series array that contains close prices for each bar


Indicator Curves created:


Implements a curve of type DRAW_LINE

Indicators Used:



Custom Indicators Used:

Order Management characteristics:
Checks for the total of closed orders
Checks for the total of open orders

Other Features:

It issuies visual alerts to the screen