//+------------------------------------------------------------------+ //| 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