Equity_virtual

Author: Copyright � 2009, Xupypr
Price Data Components
Series array that contains close prices for each barSeries array that contains open prices of each barSeries array that contains open prices of each barSeries array that contains close prices for each bar
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
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++;
 }
}
//+------------------------------------------------------------------+

Comments