Equity_virtual





//+------------------------------------------------------------------+
//|                                               Equity_virtual.mq4 |
//|                                         Copyright © 2009, Xupypr |
//|                              http://www.mql4.com/ru/users/Xupypr |
//|                                             Âåðñèÿ îò 06.10.2009 |
//|                                 http://codebase.mql4.com/ru/5389 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Xupypr"
#property link      "http://www.mql4.com/ru/users/Xupypr"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 SteelBlue
#property indicator_color2 OrangeRed
#property indicator_color3 LimeGreen
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 2

//------------- Òîðãîâûå ïàðàìåòðû
extern string   Default_Symbols=""; // Ýòà ñòðîêà áóäåò äîáàâëÿòüñÿ â îïèñàíèå íîâûõ òðåíäîâûõ ëèíèé àâòîìàòè÷åñêè, íî åñëè îíà ïóñòàÿ, òî â îïèñàíèå áóäåò äîáàâëåí òåêóùèé ñèìâîë
extern double   Default_Lot=0.1;    // Ðàçìåð ëîòà ïî óìîë÷àíèþ, åñëè îí íå óêàçàí äîïîëíèòåëüíî ïîñëå íàçâàíèÿ èíñòðóìåíòà â îïèñàíèè òðåíäîâîé ëèíèè
extern bool     Auto_Symbol=false;  // Îïèñàíèå âñåõ òðåíäîâûõ ëèíèé ðåãóëèðóåòñÿ àâòîìàòè÷åñêè ïîä òåêóùèé èíñòðóìåíò è íàïðàâëåíèå ñäåëêè, ðàçìåð ëîòà ìîæíî ðåäàêòèðîâàòü
extern bool     Use_M1=false;       // Èñïîëüçîâàòü ìèíóòíûé ÒÔ äëÿ ïîëó÷åíèÿ öåí îòêðûòèÿ
extern bool     Open_Price=true;    // Èñïîëüçîâàòü öåíû îòêðûòèÿ ñâå÷åé äëÿ ðàñ÷¸òà ïîçèöèé, èíà÷å - öåíû çàêðûòèÿ
extern bool     Use_MM=false;       // Èñïîëüçîâàòü Money Management (âìåñòî ëîòà ïîäðàçóìåâàåòñÿ ÷àñòü ñðåäñòâ)
extern int      Deposit=10000;      // Íà÷àëüíûé äåïîçèò

//------------- Âíåøíèé âèä èíäèêàòîðà
extern bool     Show_Total=true;    // Îòîáðàæàòü îáùèå ñðåäñòâà (ýêâèòè)
extern bool     Show_Buy=false;     // Îòîáðàæàòü ñðåäñòâà ïîçèöèé buy (îò íà÷àëüíîãî äåïîçèòà)
extern bool     Show_Sell=false;    // Îòîáðàæàòü ñðåäñòâà ïîçèöèé sell (îò íà÷àëüíîãî äåïîçèòà)
extern bool     Show_Info=true;     // Îòîáðàæàòü èíôîðìàöèþ î ïðîñàäêàõ, ôàêòîð âîññòàíîâëåíèÿ è ñòàòèñòèêó ïî ñäåëêàì
extern bool     Show_Vline=true;    // Îòîáðàæàòü âåðòèêàëüíûå ëèíèè íà ìåñòå îòêðûòèÿ/çàêðûòèÿ ïîçèöèé
extern color    Profit_Color=Navy;  // Öâåò ïðèáûëè
extern color    Loss_Color=Maroon;  // Öâåò óáûòêîâ
extern color    Trend_Color1=Blue;  // Öâåò òðåíäîâûõ ëèíèé äëÿ 1-îé ñòðàòåãèè
extern color    Revers_Color1=Red;  // Öâåò òðåíäîâûõ ëèíèé äëÿ 1-îé ñòðàòåãèè ñ ïåðåâîðîòîì
extern color    Trend_Color2=Green; // Öâåò òðåíäîâûõ ëèíèé äëÿ 2-îé ñòðàòåãèè
extern color    Revers_Color2=Gold; // Öâåò òðåíäîâûõ ëèíèé äëÿ 2-îé ñòðàòåãèè ñ ïåðåâîðîòîì

//------------- Íàñòðîéêà ñèãíàëîâ î ïðîñàäêå
extern double   Alert_Drawdown=0;   // Ïðåäóïðåæäàòü î ïðîñàäêå ñðåäñòâ â ïðîöåíòàõ çà ïåðèîä (0 - îòêëþ÷èòü)
extern double   Max_Drawdown=20;    // Ìàêñèìàëüíî äîïóñòèìàÿ ïðîñàäêà â ïðîöåíòàõ çà ïåðèîä ("êðàñíàÿ çîíà")
extern bool     Current_Day=true;   // Ïðîñàäêà áóäåò íàáëþäàòüñÿ òîëüêî çà òåêóùèé äåíü
extern datetime Begin_Monitoring=D'2009.08.17 00:00'; // Íà÷àëî íàáëþäåíèÿ çà ïðîñàäêîé (åñëè Current_Day=false)

//------------- Îòîáðàæåíèå è îáíîâëåíèå
extern int      Time_Refresh=3;     // Ïåðåñ÷¸ò èíäèêàòîðà ñ íîâûì òèêîì, íî íå ÷àùå îäíîãî ðàçà çà óêàçàííîå êîëè÷åñòâî ñåêóíä
extern datetime Time_Begin=D'2001.01.01 01:01'; // Íà÷àëî äèàïàçîíà îòðèñîâêè èíäèêàòîðà
extern datetime Time_End=D'2011.11.11 11:11';   // Êîíåö äèàïàçîíà îòðèñîâêè èíäèêàòîðà
extern string   Uniq_String="Virtual_5389"; // Óíèêàëüíàÿ ñòðîêà äëÿ èäåíòèôèêàöèè èíäèêàòîðà è åãî ãðàô. îáúåêòîâ

// Ïîçèöèè â èíäèêàòîðå çàäàþòñÿ òîëüêî ñ ïîìîùüþ òðåíäîâûõ ëèíèé îïðåäåëåííîãî öâåòà íà ãðàôèêå èíñòðóìåíòà.
// Ïóñòàÿ ñòðîêà îïèñàíèÿ ëèíèè çàïîëíÿåòñÿ àâòîìàòè÷åñêè, èëè ïàêåòîì ïî óìîë÷àíèþ (Default_Symbols) èëè òåêóùèì ñèìâîëîì.
// Ïîëîæåíèå ëèíèè îïðåäåëÿåò âðåìÿ îòêðûòèÿ è çàêðûòèÿ ïàêåòà. Îñóùåñòâëÿåòñÿ àâòîìàòè÷åñêàÿ ïðèâÿçêà ëèíèè ê öåíàì îòêðûòèÿ/çàêðûòèÿ ñâå÷åé.
// Àâòîìàòè÷åñêàÿ ïðèâÿçêà äåéñòâóåò â òåõ ñëó÷àÿõ, êîãäà òåêóùèé èíñòðóìåíò ïðèñóòñòâóåò â îïèñàíèè ëèíèè.
//  îïèñàíèè ñàìîñòîÿòåëüíî ìîæíî óêàçàòü íóæíûå èíñòðóìåíòû ÷åðåç ïðîáåë, ãäå çíàê îïðåäåëÿåò òèï îïåðàöèè (EURUSD+ GBPUSD-).
// Ïîñëå çíàêà ìîæåò äîïèñûâàòüñÿ ðàçìåð ëîòà (EURUSD+1 GBPUSD-0.7). Åñëè ðàçìåð ëîòà íå äîïèñàí, ïðèìåíÿåòñÿ ëîò ïî óìîë÷àíèþ (Default_Lot).
// Êîëè÷åñòâî èíñòðóìåíòîâ â ïàêåòàõ ïðîèçâîëüíîå è îãðàíè÷åíî äëèíîé ñòðîêè.
// Ñàìîñòîÿòåëüíî ìåíÿòü íàçâàíèå ëèíèè íå îáÿçàòåëüíî. Çà èñêëþ÷åíèåì ñëó÷àåâ, êîãäà íåîáõîäèìî óêàçàòü òî÷íóþ öåíó âõîäà/âûõîäà èç ïîçèöèè.
// Òîãäà â íàçâàíèè ëèíèè ñëåäóåò âíåñòè ñëåäóþùèå èçìåíåíèÿ. Äîáàâèòü ñòðîêó âèäà "[-100,150]", ãäå -100 êîððåêöèÿ âõîäà, 150 - âûõîäà.
// Òàêèì îáðàçîì öåíà îòêðûòèÿ è çàêðûòèÿ ïîçèöèè áóäåò ñêîððåêòèðîâàíà íà ýòó âåëè÷èíó.
// Äëÿ òîãî ÷òîáû ýìóëèðîâàòü ÷àñòè÷íîå çàêðûòèå ïîçèöèè, íóæíî ñîâìåñòèòü êîíåö îäíîé òðåíäîâîé ëèíèè ñ íà÷àëîì äðóãîé.
// Ïðè÷¸ì ó íîâîé ïîçèöèè, ïîìèìî óìåíüøåíèÿ îáú¸ìà, ñëåäóåò âû÷åñòü ñïðåä. Äëÿ ýòîãî â íàçâàíèå ëèíèè äîñòàòî÷íî äîáàâèòü ñèìâîë "$".

int      Total,TrendTotal,Window;
string   Currency,ShortName;
double   TotalEquity[],BuyEquity[],SellEquity[];
double   BuyBalance,SellBalance,MaxPeak,MaxProfit,PrevEquity;
double   AbsDrawdown,MaxDrawdown,RelDrawdown,Drawdown,RecoveryFactor;
datetime TrendTime[][2];

int      OpenBar[];    // Íîìåð áàðà îòêðûòèÿ
int      CloseBar[];   // Íîìåð áàðà çàêðûòèÿ
int      Type[];       // Òèï îïåðàöèè
string   Instrument[]; // Èíñòðóìåíò
double   Lots[];       // Êîëè÷åñòâî ëîòîâ
double   OpenPrice[];  // Öåíà îòêðûòèÿ
double   ClosePrice[]; // Öåíà çàêðûòèÿ

//+------------------------------------------------------------------+
//|  Custom indicator initialization function                        |
//+------------------------------------------------------------------+
int init()
{
 SetIndexBuffer(0,BuyEquity);
 SetIndexLabel(0,"Buy");
 SetIndexStyle(0,DRAW_LINE);
 SetIndexBuffer(1,SellEquity);
 SetIndexLabel(1,"Sell");
 SetIndexStyle(1,DRAW_LINE);
 SetIndexBuffer(2,TotalEquity);
 SetIndexLabel(2,"Total");
 SetIndexStyle(2,DRAW_LINE);
 ShortName="Equity_virtual";
 if (Show_Buy)   ShortName=StringConcatenate(ShortName," Buy");
 if (Show_Sell)  ShortName=StringConcatenate(ShortName," Sell");
 if (Show_Total) ShortName=StringConcatenate(ShortName," Total");
 IndicatorShortName(ShortName);
 IndicatorDigits(2);
 return(0);
}
//+------------------------------------------------------------------+
//|  Custom indicator deinitialization function                      |
//+------------------------------------------------------------------+
int deinit()
{
 int reason=UninitializeReason();
 if (reason==1 || reason==3) return(0);
 int total=ObjectsTotal()-1;
 for (int i=total;i>=0;i--)
 {
  string name=ObjectName(i);
  if (StringFind(name,Uniq_String)!=-1) ObjectDelete(name);
 }
 return(0);
}
//+------------------------------------------------------------------+
//|  Custom indicator iteration function                             |
//+------------------------------------------------------------------+
int start()
{
 static int tick;
 static string minfosymbols="";
 double buyprofitloss,sellprofitloss,spread,lotsize,profit,rprofit,gp=0,gl=0,lpt=0,llt=0;
 int bar,i,j,start,finish,sp=0,lp=0,psp=0,plp=0,lsp=0,llp=0;
 string text,pf="0.00",ep="0.00",spw="0.00",lpw="0.00",ptt="0.00",ltt="0.00",apt="0.00",alt="0.00";
 
 if (GetTickCount()-tick>Time_Refresh*1000) tick=GetTickCount();
 else return(0);
 Total=0;
 TrendTotal=0;
 for (i=0;i<ObjectsTotal();i++)
 {
  string objectname=ObjectName(i);
  if (ObjectFind(objectname)>0) continue;
  if (ObjectType(objectname)!=OBJ_TREND) continue;
  color objectcolor=ObjectGet(objectname,OBJPROP_COLOR);
  if (objectcolor==Trend_Color1 || objectcolor==Revers_Color1) SetPosition(objectname,Revers_Color1);
  else if (objectcolor==Trend_Color2 || objectcolor==Revers_Color2) SetPosition(objectname,Revers_Color2);
 }
 if (ArraySize(OpenBar)>Total)
 {
  ArrayResize(OpenBar,Total);
  ArrayResize(Instrument,Total);
  ArrayResize(Type,Total);
  ArrayResize(OpenPrice,Total);
  ArrayResize(Lots,Total);
  ArrayResize(CloseBar,Total);
  ArrayResize(ClosePrice,Total);
 }
 if (Show_Total) ArrayInitialize(TotalEquity,Deposit);
 if (Show_Buy)   ArrayInitialize(BuyEquity,Deposit);
 if (Show_Sell)  ArrayInitialize(SellEquity,Deposit);
 if (Total==0) return(0);
 AbsDrawdown=0.0;
 MaxDrawdown=0.0;
 RelDrawdown=0.0;
 BuyBalance=0.0;
 SellBalance=0.0;
 MaxPeak=0.0;
 MaxProfit=Deposit;
 PrevEquity=Deposit;
 start=OpenBar[ArrayMaximum(OpenBar)];
 finish=iBarShift(NULL,0,Time_End);
 for (i=start;i>=finish;i--)
 {
  buyprofitloss=0.0;
  sellprofitloss=0.0;
  for (j=0;j<Total;j++)
  {
   if (OpenBar[j]>=i && CloseBar[j]<=i)
   {
    if (MarketInfo(Instrument[j],MODE_POINT)==0)
    {
     if (StringFind(minfosymbols,Instrument[j])==-1)
     {
      Alert("Â îáçîðå ðûíêà íå õâàòàåò "+Instrument[j]);
      minfosymbols=StringConcatenate(minfosymbols," ",Instrument[j]);
     }
     continue;
    }
    bar=iBarShift(Instrument[j],0,Time[i]);
    lotsize=LotSize(Instrument[j],Time[i]);
    if (Use_MM && OpenBar[j]==i) Lots[j]=NormalizeDouble(PrevEquity/1000*Lots[j],2);
    if (Type[j]==OP_BUY)
    {
     if (CloseBar[j]==i)
     {
      profit=(ClosePrice[j]-OpenPrice[j])*Lots[j]*lotsize;
      BuyBalance+=profit;
      if (profit>lpt) lpt=profit;
      if (profit<llt) llt=profit;
      lp++;
      if (profit>=0)
      {
       gp+=profit;
       plp++;
      }
      else
      {
       gl-=profit;
       llp++;
      }
     }
     else buyprofitloss+=(iClose(Instrument[j],0,bar)-OpenPrice[j])*Lots[j]*lotsize;
    } 
    else
    {
     spread=MarketInfo(Instrument[j],MODE_POINT)*MarketInfo(Instrument[j],MODE_SPREAD);
     if (CloseBar[j]==i)
     {
      profit=(OpenPrice[j]-ClosePrice[j]-spread)*Lots[j]*lotsize;
      SellBalance+=profit;
      if (profit>lpt) lpt=profit;
      if (profit<llt) llt=profit;
      sp++;
      if (profit>=0)
      {
       gp+=profit;
       psp++;
      }
      else
      {
       gl-=profit;
       lsp++;
      }
     }
     else sellprofitloss+=(OpenPrice[j]-iClose(Instrument[j],0,bar)-spread)*Lots[j]*lotsize;
    }
   }
  }
  PrevEquity=NormalizeDouble(Deposit+BuyBalance+SellBalance+buyprofitloss+sellprofitloss,2);
  if (Show_Total) TotalEquity[i]=PrevEquity;
  if (Show_Buy)   BuyEquity[i]=NormalizeDouble(Deposit+BuyBalance+buyprofitloss,2);
  if (Show_Sell)  SellEquity[i]=NormalizeDouble(Deposit+SellBalance+sellprofitloss,2);
  if (Show_Info && TotalEquity[i]>0)
  {
   if (AbsDrawdown<Deposit-TotalEquity[i]) AbsDrawdown=Deposit-TotalEquity[i];
   if (PrevEquity>MaxProfit) MaxProfit=TotalEquity[i];
   if (MaxDrawdown<MaxProfit-TotalEquity[i])
   {
    MaxDrawdown=MaxProfit-TotalEquity[i];
    MaxPeak=MaxProfit;
    if (MaxPeak>0)
    {
     double relative=100*MaxDrawdown/MaxPeak;
     if (RelDrawdown<relative)
     {
      RelDrawdown=relative;
      Drawdown=MaxDrawdown;
     }
    }
   }
  }
 }
 IndicatorShortName(Uniq_String);
 Window=WindowFind(Uniq_String);
 IndicatorShortName(ShortName);
 Currency=AccountCurrency();
 if (Currency=="USD") Currency="$";
 finish=ArrayRange(TrendTime,0);
 if (finish>0) ArraySort(TrendTime);
 if (finish<TrendTotal) finish=TrendTotal;
 for (i=1;i<=finish;i++)
 {
  string open=StringConcatenate("#",i," in");
  string close=StringConcatenate("#",i," out");
  if (Show_Vline)
  {
   int openbar=iBarShift(NULL,0,TrendTime[i-1][0]);
   int closebar=iBarShift(NULL,0,TrendTime[i-1][1]);
   profit=TotalEquity[closebar]-TotalEquity[openbar+1];
   if (TotalEquity[openbar+1]>0) rprofit=100*profit/TotalEquity[openbar+1];
   if (profit>=0) objectcolor=Profit_Color;
   else objectcolor=Loss_Color;
   text=StringConcatenate(close," Profit: ",DoubleToStr(profit,2)," ",Currency," (",DoubleToStr(rprofit,2),"%)",
                                " MaxDD: ",DoubleToStr(MaxDrawdown(openbar+1,closebar),2)," ",Currency,
                                " Bars: ",openbar-closebar);
   LineCreate(open,OBJ_VLINE,1,objectcolor,open,TrendTime[i-1][0],0);
   LineCreate(close,OBJ_VLINE,1,objectcolor,text,TrendTime[i-1][1],0);
   if (i>TrendTotal)
   {
    LineDelete(open);
    LineDelete(close);
   }
  }
  else
  {
   LineDelete(open);
   LineDelete(close);
  }
 }
 if (ArrayRange(TrendTime,0)>TrendTotal) ArrayResize(TrendTime,TrendTotal);
 
 if (Show_Total)
 {
  profit=TotalEquity[0]-Deposit;
  if (Deposit>0) rprofit=100*profit/Deposit;
  else rprofit=0;
  text=StringConcatenate("Total Profit: ",DoubleToStr(profit,2)," ",Currency," (",DoubleToStr(rprofit,2),"%)");
  LineCreate("Total Equity",OBJ_HLINE,1,LimeGreen,text,0,TotalEquity[0]);
 }
 else LineDelete("Total Equity");
 if (Show_Buy)
 {
  profit=BuyEquity[0]-Deposit;
  if (Deposit>0) rprofit=100*profit/Deposit;
  else rprofit=0;
  text=StringConcatenate("Buy Profit: ",DoubleToStr(profit,2)," ",Currency," (",DoubleToStr(rprofit,2),"%)");
  LineCreate("Buy Equity",OBJ_HLINE,1,SteelBlue,text,0,BuyEquity[0]);
 }
 else LineDelete("Buy Equity");
 if (Show_Sell)
 {
  profit=SellEquity[0]-Deposit;
  if (Deposit>0) rprofit=100*profit/Deposit;
  else rprofit=0;
  text=StringConcatenate("Sell Profit: ",DoubleToStr(profit,2)," ",Currency," (",DoubleToStr(rprofit,2),"%)");
  LineCreate("Sell Equity",OBJ_HLINE,1,OrangeRed,text,0,SellEquity[0]);
 }
 else LineDelete("Sell Equity");
 if (Show_Info)
 {
  text=StringConcatenate(": ",start," bars from ",TimeToStr(Time[start]));
  LabelCreate("History",text,0);
  if (MaxDrawdown>0)
  {
   RecoveryFactor=(TotalEquity[0]-Deposit)/MaxDrawdown;
   text=StringConcatenate(": ",DoubleToStr(RecoveryFactor,2));
   LabelCreate("Recovery Factor",text,1);
  }
  text=StringConcatenate(": ",DoubleToStr(AbsDrawdown,2)," ",Currency);
  LabelCreate("Absolute Drawdown",text,2);
  if (MaxPeak>0)
  {
   text=StringConcatenate(": ",DoubleToStr(MaxDrawdown,2)," ",Currency," (",DoubleToStr(100*MaxDrawdown/MaxPeak,2),"%)");
   LabelCreate("Maximal Drawdown",text,3);
  }
  text=StringConcatenate(": ",DoubleToStr(RelDrawdown,2),"% (",DoubleToStr(Drawdown,2)," ",Currency,")");
  LabelCreate("Relative Drawdown",text,4);
  if (gl!=0)        pf=DoubleToStr(gp/gl,2);
  if ((sp+lp)!=0)   ep=DoubleToStr((gp-gl)/(sp+lp),2);
  if (sp!=0)        spw=DoubleToStr(100.0*psp/sp,2);
  if (lp!=0)        lpw=DoubleToStr(100.0*plp/lp,2);
  if ((sp+lp)!=0)   ptt=DoubleToStr(100.0*(psp+plp)/(sp+lp),2);
  if ((sp+lp)!=0)   ltt=DoubleToStr(100.0*(lsp+llp)/(sp+lp),2);
  if ((psp+plp)!=0) apt=DoubleToStr(gp/(psp+plp),2);
  if ((lsp+llp)!=0) alt=DoubleToStr(-gl/(lsp+llp),2);
  text=StringConcatenate(": ",DoubleToStr(gp,2)," ",Currency);
  LabelCreate("Gross Profit",text,6);
  text=StringConcatenate(": ",DoubleToStr(gl,2)," ",Currency);
  LabelCreate("Gross Loss",text,7);
  text=StringConcatenate(": ",DoubleToStr(gp-gl,2)," ",Currency);
  LabelCreate("Total Net Profit",text,8);
  text=StringConcatenate(": ",pf);
  LabelCreate("Profit Factor",text,9);
  text=StringConcatenate(": ",ep);
  LabelCreate("Expected Payoff",text,10);
  text=StringConcatenate(": ",sp+lp);
  LabelCreate("Total Trades",text,11);
  text=StringConcatenate(": ",sp," (",spw,"%)");
  LabelCreate("Short Positions (won %)",text,12);
  text=StringConcatenate(": ",lp," (",lpw,"%)");
  LabelCreate("Long Positions (won %)",text,13);
  text=StringConcatenate(": ",psp+plp," (",ptt,"%)");
  LabelCreate("Profit Trades (% of total)",text,14);
  text=StringConcatenate(": ",lsp+llp," (",ltt,"%)");
  LabelCreate("Loss Trades (% of total)",text,15);
  text=StringConcatenate(": ",DoubleToStr(lpt,2));
  LabelCreate("Largest profit trade",text,16);
  text=StringConcatenate(": ",DoubleToStr(llt,2));
  LabelCreate("Largest loss trade",text,17);
  text=StringConcatenate(": ",apt);
  LabelCreate("Average profit trade",text,18);
  text=StringConcatenate(": ",alt);
  LabelCreate("Average loss trade",text,19);
 }
 if (Alert_Drawdown>0 && Show_Total) AlertDrawdown();
 return(0);
}
//+------------------------------------------------------------------+
//|  Ñîçäàíèå òåêñòîâîé ìåòêè                                        |
//+------------------------------------------------------------------+
void LabelCreate(string name, string str, int pos)
{
 string objectname=StringConcatenate(name," ",Uniq_String);
 if (ObjectFind(objectname)==-1)
 {
  ObjectCreate(objectname,OBJ_LABEL,Window,0,0);
  ObjectSet(objectname,OBJPROP_XDISTANCE,3);
  ObjectSet(objectname,OBJPROP_YDISTANCE,10*pos+4);
  ObjectSet(objectname,OBJPROP_CORNER,1);
 }
 ObjectSetText(objectname,name+str,7,"Tahoma",SlateGray);
}
//+------------------------------------------------------------------+
//|  Ñîçäàíèå ëèíèè                                                  |
//+------------------------------------------------------------------+
void LineCreate(string name, int type, int width, color clr, string str, datetime time1, double price1, datetime time2=0, double price2=0)
{
 string objectname=StringConcatenate(name," ",Uniq_String);
 if (ObjectFind(objectname)==-1)
 {
  ObjectCreate(objectname,type,Window,time1,price1,time2,price2);
  ObjectSet(objectname,OBJPROP_WIDTH,width);
  if (type==OBJ_TREND) ObjectSet(objectname,OBJPROP_RAY,false);
  if (type==OBJ_HLINE) ObjectSet(objectname,OBJPROP_STYLE,STYLE_DOT);
 }
 if (StringFind(ObjectDescription(objectname)," in")==-1) 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);
}
//+------------------------------------------------------------------+
//|  Óäàëåíèå ëèíèè                                                  |
//+------------------------------------------------------------------+
void LineDelete(string name)
{
 string objectname=StringConcatenate(name," ",Uniq_String);
 if (ObjectFind(objectname)!=-1) ObjectDelete(objectname);
}
//+------------------------------------------------------------------+
//|  Íàáëþäåíèå è ïðåäóïðåæäåíèå î ïðîñàäêàõ çà ïåðèîä               |
//+------------------------------------------------------------------+
int AlertDrawdown()
{
 int bar=0;
 color clr;
 string drawdownstr,text;
 double relative,level,curdrawdown;
 double maxpeak,maxprofit,maxdrawdown,reldrawdown,drawdown,maxDD;
 datetime time,timehigh,timelow,timemaxprofit;
     
 if (Current_Day) time=StrToTime(TimeToStr(Time[0],TIME_DATE));
 else time=Begin_Monitoring;
 if (time<Time_Begin) time=Time_Begin;
 bar=iBarShift(NULL,0,time);
 time=iTime(NULL,0,bar);
 maxprofit=0.0;
 maxdrawdown=0.0;
 reldrawdown=0.0;
 maxDD=Alert_Drawdown;
 for (int i=bar;i>=0;i--)
 {
  if (TotalEquity[i]<0) return(-1);
  if (TotalEquity[i]>maxprofit)
  {
   timemaxprofit=Time[i];
   maxprofit=TotalEquity[i];
   maxdrawdown=0.0;
   reldrawdown=0.0;
   maxDD=Alert_Drawdown;
  }
  if (maxdrawdown<maxprofit-TotalEquity[i])
  {
   maxdrawdown=maxprofit-TotalEquity[i];
   maxpeak=maxprofit;
   timehigh=timemaxprofit;
   if (maxpeak>0)
   {
    relative=NormalizeDouble(100*maxdrawdown/maxpeak,1);
    if (reldrawdown<relative)
    {
     reldrawdown=relative;
     drawdown=maxdrawdown;
     timelow=Time[i];
    }
   }
  }
 }
 text="Up";
 if (ObjectFind(text)==-1)
 {
  double max=TotalEquity[ArrayMaximum(TotalEquity)];
  ObjectCreate(text,OBJ_HLINE,Window,0,max);
  ObjectSet(text,OBJPROP_COLOR,Profit_Color);
  ObjectSetText(text,"Alert Profit");
 }
 else
 {
  if (ObjectGet(text,OBJPROP_PRICE1)<TotalEquity[0])
  {
   Alert("Óðîâåíü ñðåäñòâ ïîäíÿëñÿ äî îòìåòêè ",TotalEquity[0]," ",Currency);
   ObjectSet(text,OBJPROP_PRICE1,TotalEquity[0]);
  }
 }
 text="Down";
 if (ObjectFind(text)==-1)
 {
  double min=TotalEquity[ArrayMinimum(TotalEquity)];
  ObjectCreate(text,OBJ_HLINE,Window,0,min);
  ObjectSet(text,OBJPROP_COLOR,Loss_Color);
  ObjectSetText(text,"Alert Loss");
 }
 else
 {
  if (ObjectGet(text,OBJPROP_PRICE1)>TotalEquity[0])
  {
   Alert("Óðîâåíü ñðåäñòâ îïóñòèëñÿ äî îòìåòêè ",TotalEquity[0]," ",Currency);
   ObjectSet(text,OBJPROP_PRICE1,TotalEquity[0]);
  }
 }
 if (reldrawdown>maxDD)
 {
  maxDD=reldrawdown;
  if (maxDD>Max_Drawdown)
  {
   text=StringConcatenate("Âíèìàíèå! Ïðåâûøåí óðîâåíü äîïóñòèìîé ïðîñàäêè íà ",DoubleToStr(maxDD-Max_Drawdown,1),"%\n");
   text=StringConcatenate(text,"Äîïóñòèìàÿ ïðîñàäêà çàäàíà íà óðîâíå ",DoubleToStr(Max_Drawdown,1),"%\n");
  }
  else
  {
   text=StringConcatenate("Ïðåâûøåí óðîâåíü ñèãíàëüíîé ïðîñàäêè íà ",DoubleToStr(maxDD-Alert_Drawdown,1),"%\n");
   text=StringConcatenate(text,"Ñèãíàëüíàÿ ïðîñàäêà çàäàíà íà óðîâíå ",DoubleToStr(Alert_Drawdown,1),"%\n");
  }
  drawdownstr=StringConcatenate(DoubleToStr(reldrawdown,1),"% (",DoubleToStr(drawdown,2)," ",Currency,")");
  text=StringConcatenate(text,"Ïðîñàäêà â ñðåäñòâàõ çà òåêóùèé ïåðèîä ñîñòàâèëà ",drawdownstr,"\n");
  text=StringConcatenate(text,"Ïåðèîä ìîíèòîðèíãà: ",bar," áàðà(îâ) îò ",TimeToStr(time),"\n");
  text=StringConcatenate(text,"Íàçâàíèå èíäèêàòîðà: ",ShortName,"\n");
  text=StringConcatenate(text,"Èíäèêàòîð ðàáîòàåò íà ",Symbol(),",",StringPeriod());
  Alert(text);
  if (maxDD>Max_Drawdown) clr=Loss_Color;
  else clr=DarkOrange;
  LineCreate("Drawdown Line",OBJ_TREND,2,clr,"       "+drawdownstr,timehigh,maxpeak,timelow,maxpeak-drawdown);
 }
 else LineDelete("Drawdown Line");
 LineCreate("Begin Monitoring",OBJ_VLINE,1,SlateGray,"Begin Monitoring",time,0);
 level=NormalizeDouble(maxprofit,2);
 LineCreate("Max Profit",OBJ_TREND,1,Profit_Color,"Max Profit",timemaxprofit,level,Time[0],level);
 level=NormalizeDouble(maxprofit*(1-Alert_Drawdown/100),2);
 LineCreate("Alert Drawdown",OBJ_TREND,1,DarkOrange,"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,Loss_Color,"Max Drawdown "+DoubleToStr(Max_Drawdown,1)+"%",timemaxprofit,level,Time[0],level);
 if (Show_Info)
 {
  curdrawdown=maxprofit-TotalEquity[0];
  text=StringConcatenate(": ",DoubleToStr(curdrawdown,2)," ",Currency," (",DoubleToStr(100*curdrawdown/maxprofit,2),"%)");
  LabelCreate("Current Drawdown",text,5);
 }
}
//+------------------------------------------------------------------+
//|  Ñòðîêîâîå îáîçíà÷åíèå ïåðèîäà                                   |
//+------------------------------------------------------------------+
string StringPeriod()
{
 string period;
 switch(Period())
 {
  case PERIOD_M1:  period="M1";  break;
  case PERIOD_M5:  period="M5";  break;
  case PERIOD_M15: period="M15"; break;
  case PERIOD_M30: period="M30"; break;
  case PERIOD_H1:  period="H1";  break;
  case PERIOD_H4:  period="H4";  break;
  case PERIOD_D1:  period="D1";  break;
  case PERIOD_W1:  period="W1";  break;
  case PERIOD_MN1: period="MN1";
 }
 return(period);
}
//+------------------------------------------------------------------+
//|  Ðàñ÷¸ò ìàêñèìàëüíîé ïðîñàäêè çà ïåðèîä                          |
//+------------------------------------------------------------------+
double MaxDrawdown(int in, int out)
{
 double maxprofit=0.0, maxdd=0.0;
 for (int i=in;i>=out;i--)
 {
  if (TotalEquity[i]<0) return(-1);
  if (TotalEquity[i]>maxprofit) maxprofit=TotalEquity[i];
  if (maxdd<maxprofit-TotalEquity[i]) maxdd=maxprofit-TotalEquity[i];
 }
 return(maxdd);
}
//+------------------------------------------------------------------+
//|  Îïðåäåëåíèå ðàçìåðà êîíòðàêòà                                   |
//+------------------------------------------------------------------+
double LotSize(string symbol, datetime tbar)
{
 double size,close1,close2;
 string BQ,currency=Currency;
 
 if (currency=="") currency="USD";
 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")
   {
    close1=iClose(symbol,0,sbar);
    if (close1>0) size=size/close1;
   }
   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);
    close1=iClose(symbol,0,sbar);
    close2=iClose(BQ,0,BQbar);
    if (close1>0 && close2>0)
    {
     if (StringSubstr(BQ,0,3)=="USD") size=size/close2/close1;
     else size=size*close2/close1;
    }
   }
  } 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;
   close1=iClose(BQ,0,iBarShift(BQ,0,tbar));
   if (close1>0) size*=close1;
  }
  else
  {
   close1=iClose(BQ,0,iBarShift(BQ,0,tbar));
   if (close1>0) size/=close1;
  }
 }
 return(size);
}
//+------------------------------------------------------------------+
//|  Óñòàíîâêà ïàðàìåòðîâ ïîçèöèè ïî òðåíäîâîé ëèíèè                 |
//+------------------------------------------------------------------+
bool SetPosition(string name, color revers)
{
 double corrin=0,corrout=0,priceopen,priceclose;
 int timeframe=0;
  
 datetime timeopen=ObjectGet(name,OBJPROP_TIME1);
 datetime timeclose=ObjectGet(name,OBJPROP_TIME2);
 if (timeopen==timeclose) return(false);
 if (timeopen>timeclose)
 {
  timeopen=ObjectGet(name,OBJPROP_TIME2);
  timeclose=ObjectGet(name,OBJPROP_TIME1);
 }
 if (timeopen>TimeCurrent() || timeopen<Time_Begin || timeopen>Time_End) return(false);
 int pos1=StringFind(name,"[");
 int pos2=StringFind(name,",");
 if (pos1!=-1 && pos2!=-1) corrin=StrToDouble(StringSubstr(name,pos1+1,pos2-pos1-1));
 pos1=StringFind(name,"]");
 if (pos1!=-1 && pos2!=-1) corrout=StrToDouble(StringSubstr(name,pos2+1,pos1-pos2-1));
 if (Use_M1) timeframe=PERIOD_M1;
 if (Open_Price)
 {
  priceopen=iOpen(NULL,timeframe,iBarShift(NULL,timeframe,timeopen))+corrin*MarketInfo(Symbol(),MODE_POINT);
  priceclose=iOpen(NULL,timeframe,iBarShift(NULL,timeframe,timeclose))+corrout*MarketInfo(Symbol(),MODE_POINT);
 }
 else
 {
  priceopen=iClose(NULL,timeframe,iBarShift(NULL,timeframe,timeopen))+corrin*MarketInfo(Symbol(),MODE_POINT);
  priceclose=iClose(NULL,timeframe,iBarShift(NULL,timeframe,timeclose))+corrout*MarketInfo(Symbol(),MODE_POINT);
 }
 string description=ObjectDescription(name);
 if (description=="" || Auto_Symbol)
 {
  if (Default_Symbols!="" && !Auto_Symbol) description=Default_Symbols;
  else
  {
   if (Auto_Symbol)
   {
    string lot="";
    pos1=StringFind(description,Symbol());
    if (pos1!=-1)
    {
     pos2=pos1+StringLen(Symbol())+1;
     lot=StringSubstr(description,pos2);          
     if (StrToDouble(lot)==0) lot="";
    }
   }
   description=Symbol();
   if (priceopen<priceclose) description=StringConcatenate(description,"+");
   else description=StringConcatenate(description,"-");
   if (Auto_Symbol && lot!="") description=StringConcatenate(description,lot);
  }
  ObjectSetText(name,description);
 }
 if (StringFind(description,Symbol())!=-1)
 {
  if (timeclose>TimeCurrent())
  {
   if (ObjectGet(name,OBJPROP_TIME2)<ObjectGet(name,OBJPROP_TIME1))
   {
    ObjectSet(name,OBJPROP_TIME2,ObjectGet(name,OBJPROP_TIME1));
    ObjectSet(name,OBJPROP_PRICE2,ObjectGet(name,OBJPROP_PRICE1));
   }
  }
  else
  {
   if (ObjectGet(name,OBJPROP_TIME2)!=timeclose) ObjectSet(name,OBJPROP_TIME2,timeclose);
   if (ObjectGet(name,OBJPROP_PRICE2)!=priceclose) ObjectSet(name,OBJPROP_PRICE2,priceclose);
  }
  if (ObjectGet(name,OBJPROP_TIME1)!=timeopen) ObjectSet(name,OBJPROP_TIME1,timeopen);
  if (ObjectGet(name,OBJPROP_PRICE1)!=priceopen) ObjectSet(name,OBJPROP_PRICE1,priceopen);
 }
 TrendTotal++;
 if (Show_Vline)
 {
  if (ArrayRange(TrendTime,0)<TrendTotal) ArrayResize(TrendTime,TrendTotal);
  TrendTime[TrendTotal-1][0]=timeopen;
  TrendTime[TrendTotal-1][1]=timeclose;
 }
 color objcolor=ObjectGet(name,OBJPROP_COLOR);
 int length=StringLen(description);
 pos2=0;
 while (pos2<length)
 {
  Total++;
  if (ArraySize(OpenBar)<Total)
  {
   ArrayResize(OpenBar,Total);
   ArrayResize(Instrument,Total);
   ArrayResize(Type,Total);
   ArrayResize(OpenPrice,Total);
   ArrayResize(Lots,Total);
   ArrayResize(CloseBar,Total);
   ArrayResize(ClosePrice,Total);
  }
  OpenBar[Total-1]=iBarShift(NULL,0,timeopen);
  CloseBar[Total-1]=iBarShift(NULL,0,timeclose);
  pos1=pos2;
  int char=0;
  while (char!=43 && char!=45 && char!=32)
  {
   pos2++;
   char=StringGetChar(description,pos2);
   if ((length-1)<pos2) break;
  }
  Type[Total-1]=OP_BUY;
  if (char==43 && objcolor==revers) Type[Total-1]=OP_SELL;
  if (char==45 && objcolor!=revers) Type[Total-1]=OP_SELL;
  Instrument[Total-1]=StringSubstr(description,pos1,pos2-pos1);
  if (Open_Price)
  {
   OpenPrice[Total-1]=iOpen(Instrument[Total-1],timeframe,iBarShift(Instrument[Total-1],timeframe,timeopen));
   ClosePrice[Total-1]=iOpen(Instrument[Total-1],timeframe,iBarShift(Instrument[Total-1],timeframe,timeclose));
  }
  else
  {
   OpenPrice[Total-1]=iClose(Instrument[Total-1],timeframe,iBarShift(Instrument[Total-1],timeframe,timeopen));
   ClosePrice[Total-1]=iClose(Instrument[Total-1],timeframe,iBarShift(Instrument[Total-1],timeframe,timeclose));
  }
  double spread=MarketInfo(Instrument[Total-1],MODE_POINT)*MarketInfo(Instrument[Total-1],MODE_SPREAD);
  if (Type[Total-1]==OP_BUY) OpenPrice[Total-1]+=spread;
  if (StringFind(name,"$")!=-1)
  {
   if (Type[Total-1]==OP_BUY) OpenPrice[Total-1]-=spread;
   if (Type[Total-1]==OP_SELL) OpenPrice[Total-1]+=spread;
  }
  if (corrin!=0) OpenPrice[Total-1]+=corrin*MarketInfo(Instrument[Total-1],MODE_POINT);
  if (corrout!=0) ClosePrice[Total-1]+=corrout*MarketInfo(Instrument[Total-1],MODE_POINT);
  pos2++;
  if (StringGetChar(description,pos2)==32 || (length-1)<pos2) Lots[Total-1]=Default_Lot;
  else
  {
   pos1=pos2;
   while(StringGetChar(description,pos2)!=32)
   {
    pos2++;
    if ((length-1)<pos2) break;
   }
   Lots[Total-1]=StrToDouble(StringSubstr(description,pos1,pos2-pos1));
  }
  pos2++;
 }
}
//+------------------------------------------------------------------+



Sample





Analysis



Market Information Used:

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


Indicator Curves created:


Implements a curve of type DRAW_LINE

Indicators Used:



Custom Indicators Used:

Order Management characteristics:

Other Features:

It issuies visual alerts to the screen