Author: Copyright © 2009, Tokman Yuriy
Price Data Components
Series array that contains tick volumes of each bar
Orders Execution
It can change open orders parameters, due to possible stepping strategyChecks for the total of open orders
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
ZigZag EA
ÿþ//+------------------------------------------------------------------+

//|                           ZigZag EA(barabashkakvn's edition).mq5 |

//|                                   Copyright © 2009, Tokman Yuriy |

//|                                            yuriytokman@gmail.com |

//+------------------------------------------------------------------+

#property copyright "Copyright © 2009, Tokman Yuriy"

#property link      "yuriytokman@gmail.com"

#property version   "1.002"

//---

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

#include <Trade\AccountInfo.mqh>

#include <Trade\OrderInfo.mqh>

#include <Expert\Money\MoneyFixedMargin.mqh>

CPositionInfo  m_position;                   // trade position object

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol;                     // symbol info object

CAccountInfo   m_account;                    // account info wrapper

COrderInfo     m_order;                      // pending orders object

CMoneyFixedMargin *m_money;

//---

enum ENUM_FIBO

  {

   level_0_0   = 0,  // 0.0% 

   level_23_6  = 1,  // 23.6%

   level_38_2  = 2,  // 38.2%

   level_50_0  = 3,  // 50.0% 

   level_61_8  = 4,  // 61.8%

   level_100_0 = 5,  // 100.0% 

   level_161_8 = 6,  // 161.8%

   level_261_8 = 7,  // 261.8%

   level_423_6 = 8,  // 423.6%

  };

//--- input parameters

input string      ____1___          = "0AB@>9:8 8=48:0B>@0 ZigZag";

input int         ExtDepth          = 12;             // Depth

input int         ExtDeviation      = 5;              // Deviation

input int         ExtBackstep       = 3;              // Backstep

//---

input string      ____2___          = "@5<O @01>BK A>25B=8:0";

input int         StartHour         = 00;             // !B0@B @01>BK G0AK

input int         StartMinute       = 01;             // !B0@B @01>BK <8=CBK

input int         StopHour          = 23;             // !B>? @01>BK G0AK

input int         StopMinute        = 59;             // !B>? @01>BK <8=CBK

//---

input string      ____3___          = "0AB@>9:8 :>@84>@0 8 >BABC?0";

input ushort      N_pips            = 5;              // BABC? 2 ?C=:B0E

input ushort      Min_Corridor      = 20;             // 8=8<0;L=K9 @07<5@ :>@84>@0

input ushort      Max_Corridor      = 100;            // 0:A8<0;L=K9 @07<5@ :>@84>@0

//---

input string      ____4___          = "0AB@>9:8 ";

input double      InpLots           = 0;              // Lots (or "Lots">0 and "Risk"==0 or "Lots"==0 and "Risk">0)

input double      Risk              = 5;              // Risk (or "Lots">0 and "Risk"==0 or "Lots"==0 and "Risk">0)

//---

input string      _____5_____       = "0AB@>9:8 A>25B=8:0";

input ENUM_FIBO   Fibo_StopLoss     = level_61_8;     //  07<5@ AB>?0 2 ?@>F5=B0E

input ENUM_FIBO   Fibo_TakeProfit   = level_161_8;    //  07<5@ B59:0 2 ?@>F5=B0E

input ushort      InpTrailingStop   = 5;              // Trailing Stop (in pips)

input ushort      InpTrailingStep   = 5;              // Trailing Step (in pips)

input bool        Line              = false;          // >:07K20BL ;8=88 :0=0;0

input ulong       m_magic           = 154897;         // magic number

//---

ulong             m_slippage=10;                      // slippage

//--- ;>10;L=K5 ?5@5<5==K5 A>25B=8:0

int           NumberAccount    = 0;             // ><5@ B>@3>2>3> AGQB0

bool          gbDisabled       = false;         // $;03 1;>:8@>2:8 A>25B=8:0

bool          gbNoInit         = false;         // $;03 =5C40G=>9 8=8F80;870F88

double current_high = 0, current_low = 0;

double          ppB = 0,         ppS = 0;

int    StopLoss     = 0;

int    TakeProfit   = 0;



double         ExtN_pips=0.0;

double         ExtMin_Corridor=0.0;

double         ExtMax_Corridor=0.0;

double         ExtTrailingStop=0.0;

double         ExtTrailingStep=0.0;



int            handle_iCustom;               // variable for storing the handle of the iCustom indicator 



double         m_adjusted_point;             // point value adjusted for 3 or 5 points

//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

//---

   if(StartHour>23)

     {

      string text=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")?

                  "0@0<5B@ \"!B0@B @01>BK G0AK\" =5 <>65B 1KBL 1>;LH5 23 G0A>2!":

                  "Parameter \"!B0@B @01>BK G0AK\" can not be more than 23 hours!";

      Alert(__FUNCTION__," ERROR! ",text);

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(StopHour>23)

     {

      string text=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")?

                  "0@0<5B@ \"!B>? @01>BK G0AK\" =5 <>65B 1KBL 1>;LH5 23 G0A>2!":

                  "Parameter \"!B>? @01>BK G0AK\" can not be more than 23 hours!";

      Alert(__FUNCTION__," ERROR! ",text);

      return(INIT_PARAMETERS_INCORRECT);

     }

//---

   if(InpTrailingStop!=0 && InpTrailingStep==0)

     {

      string text=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")?

                  ""@59;8=3 =52>7<>65=: ?0@0<5B@ \"Trailing Step\" @025= =C;N!":

                  "Trailing is not possible: parameter \"Trailing Step\" is zero!";

      Alert(__FUNCTION__," ERROR! ",text);

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(!m_symbol.Name(Symbol())) // sets symbol name

      return(INIT_FAILED);

   RefreshRates();

//---

   m_trade.SetExpertMagicNumber(m_magic);

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(m_symbol.Name());

   m_trade.SetDeviationInPoints(m_slippage);

//--- tuning for 3 or 5 digits

   int digits_adjust=1;

   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)

      digits_adjust=10;

   m_adjusted_point=m_symbol.Point()*digits_adjust;



   ExtN_pips      = N_pips          * m_adjusted_point;

   ExtMin_Corridor= Min_Corridor    * m_adjusted_point;

   ExtMax_Corridor= Max_Corridor    * m_adjusted_point;

   ExtTrailingStop= InpTrailingStop * m_adjusted_point;

   ExtTrailingStep= InpTrailingStep * m_adjusted_point;

//---

   if(!LotsOrRisk(InpLots,Risk,digits_adjust))

      return(INIT_PARAMETERS_INCORRECT);

//---

   if(m_money!=NULL)

      delete m_money;

   m_money=new CMoneyFixedMargin;

   if(m_money!=NULL)

     {

      if(!m_money.Init(GetPointer(m_symbol),Period(),m_symbol.Point()*digits_adjust))

         return(INIT_FAILED);

      m_money.Percent(Risk);

     }

   else

     {

      Print(__FUNCTION__,", ERROR: Object CMoneyFixedMargin is NULL");

      return(INIT_FAILED);

     }

//--- create handle of the indicator iCustom

   handle_iCustom=iCustom(m_symbol.Name(),Period(),"Examples\\ZigZag");

//--- if the handle is not created 

   if(handle_iCustom==INVALID_HANDLE)

     {

      //--- tell about the failure and output the error code 

      PrintFormat("Failed to create handle of the iCustom indicator for the symbol %s/%s, error code %d",

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      if(m_money!=NULL)

         delete m_money;

      //--- the indicator is stopped early 

      return(INIT_FAILED);

     }

//---

   if(Line)

     {

      HLineCreate(0,"00",0,0.0,clrYellow);

      HLineCreate(0,"high",0,0.0,clrBlue);

      HLineCreate(0,"low",0,0.0,clrRed);

     }

//---

   return(INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//---

   if(m_money!=NULL)

      delete m_money;



   if(Line)

     {

      HLineDelete(0,"00");

      HLineDelete(0,"high");

      HLineDelete(0,"low");

     }

  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {

//---

   Trailing();

//---

   double array_results[];

   if(!SearchZigZagExtremums(3,array_results))

      return;



   double high=0.0,low=0.0;

   double room_0 = array_results[0];

   double room_1 = array_results[1];

   double room_2 = array_results[2];

//--- =0E>48< 25@E 8 =87

   if(room_1>room_2)

     {

      high=room_1;

      low=room_2;

     }

   else

     {

      high=room_2;

      low=room_1;

     }

   double size_corridor=high-low;      // H8@8=0 :>@84>@0

   double STOPLEVEL=m_symbol.StopsLevel()*m_symbol.Point();

//--- 2KG8A;O5< !" 8 "

   StopLoss=(int)((size_corridor/100.0*GetFibo(Fibo_StopLoss))/m_symbol.Point());//  ???

   TakeProfit=(int)(((size_corridor/100.0*Fibo_TakeProfit)-size_corridor)/m_symbol.Point());//  ???

   ppB        = MathRound(high/m_symbol.Point() + N_pips )*m_symbol.Point();  //???

   ppS        = MathRound(low/m_symbol.Point()  - N_pips )*m_symbol.Point();  //???

//--- ?@>@8A>2:0 ;8=89 4;O 0=0;870

   if(Line)

     {

      HLineMove(0,"00",room_0);

      HLineMove(0,"high",high);

      HLineMove(0,"low",low);

     }

//--- C40;O5< >B;>6:C 5A;8 5ABL @K=>G=K9 >@45@

   if(IsPositionExists())// 5ABL >B:@KB0O ?>78F8O

      if(IsPendingOrdersExists())

        {

         DeleteAllPendingOrders();// C40;O5< >B;>6:8

         return;

        }

//---

   double sl=0,tp=0,ti=0;



   if(size_corridor>ExtMin_Corridor && size_corridor<ExtMax_Corridor // :>@84>@ 4>?CAB8<>9 25;8G8=K

      && high>room_0+STOPLEVEL && low<room_0-STOPLEVEL) // =C;520O B>G:0 7830 =0E>48BAO 2 :>@84>@5   

     {

      if(!IsPositionExists()) //=5B >B:@KBKE ?>78F89 

        {

         int   count_buy_stop    = 0;

         ulong ticket_buy_stop   = 0;

         int   count_sell_stop   = 0;

         ulong ticket_sell_stop  = 0;

         CalculateAllPendingOrders(count_buy_stop,ticket_buy_stop,count_sell_stop,ticket_sell_stop);

         if(count_buy_stop>1 || count_sell_stop>1)

            return;



         if(count_buy_stop==0) // =5B 109AB>?0

           {

            if(StopLoss>0)

               sl=ppB-StopLoss*m_symbol.Point();

            else

               sl=0;

            if(TakeProfit>0)

               tp=ppB+TakeProfit*m_symbol.Point();

            else

               tp=0;

            if(!RefreshRates())

               return;

            PendingBuyStop(ppB,sl,tp); // CAB0=02;8205< 109 AB>?

           }

         else if(count_buy_stop==1) // 5ABL 109AB>?

           {

            if(m_order.Select(ticket_buy_stop))

               if(!CompareDoubles(m_order.PriceOpen(),ppB,m_symbol.Digits()))

                 {

                  //--- <>48D8F8@C5<

                  if(StopLoss>0)

                     sl=ppB-StopLoss*m_symbol.Point();

                  else

                     sl=0;

                  if(TakeProfit>0)

                     tp=ppB+TakeProfit*m_symbol.Point();

                  else

                     tp=0;

                  if(!RefreshRates())

                     return;

                  if(!m_trade.OrderModify(ticket_buy_stop,ppB,sl,tp,m_order.TypeTime(),m_order.TimeExpiration()))

                     Print("Modify BUY_STOP -> false. Result Retcode: ",m_trade.ResultRetcode(),

                           ", description of Retcode: ",m_trade.ResultRetcodeDescription(),

                           ", ticket of order: ",m_trade.ResultOrder());

                 }

           }



         if(count_sell_stop==0) //=5B A5;;AB>?0     

           {

            if(StopLoss>0)

               sl=ppS+StopLoss*m_symbol.Point();

            else

               sl=0;

            if(TakeProfit>0)

               tp=ppS-TakeProfit*m_symbol.Point();

            else

               tp=0;

            if(!RefreshRates())

               return;

            PendingSellStop(ppS,sl,tp); // CAB0=02;8205< A5;; AB>?    

           }

         else if(count_sell_stop==1) // 5ABL A5;;AB>?

           {

            if(m_order.Select(ticket_sell_stop))

               if(!CompareDoubles(m_order.PriceOpen(),ppS,m_symbol.Digits()))

                 {

                  //--- <>48D8F8@C5<

                  if(StopLoss>0)

                     sl=ppS+StopLoss*m_symbol.Point();

                  else

                     sl=0;

                  if(TakeProfit>0)

                     tp=ppS-TakeProfit*m_symbol.Point();

                  else

                     tp=0;

                  if(!RefreshRates())

                     return;

                  if(!m_trade.OrderModify(ticket_sell_stop,ppS,sl,tp,m_order.TypeTime(),m_order.TimeExpiration()))

                     Print("Modify SELL_STOP -> false. Result Retcode: ",m_trade.ResultRetcode(),

                           ", description of Retcode: ",m_trade.ResultRetcodeDescription(),

                           ", ticket of order: ",m_trade.ResultOrder());

                 }

           }

        }

     }

  }

//+------------------------------------------------------------------+

//| TradeTransaction function                                        |

//+------------------------------------------------------------------+

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result)

  {

//---



  }

//+------------------------------------------------------------------+

//| Refreshes the symbol quotes data                                 |

//+------------------------------------------------------------------+

bool RefreshRates(void)

  {

//--- refresh rates

   if(!m_symbol.RefreshRates())

     {

      Print("RefreshRates error");

      return(false);

     }

//--- protection against the return value of "zero"

   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)

      return(false);

//---

   return(true);

  }

//+------------------------------------------------------------------+

//| Check the correctness of the position volume                     |

//+------------------------------------------------------------------+

bool CheckVolumeValue(double volume,string &error_description)

  {

//--- minimal allowed volume for trade operations

   double min_volume=m_symbol.LotsMin();

   if(volume<min_volume)

     {

      error_description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);

      return(false);

     }

//--- maximal allowed volume of trade operations

   double max_volume=m_symbol.LotsMax();

   if(volume>max_volume)

     {

      error_description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);

      return(false);

     }

//--- get minimal step of volume changing

   double volume_step=m_symbol.LotsStep();

   int ratio=(int)MathRound(volume/volume_step);

   if(MathAbs(ratio*volume_step-volume)>0.0000001)

     {

      error_description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",

                                     volume_step,ratio*volume_step);

      return(false);

     }

   error_description="Correct volume value";

   return(true);

  }

//+------------------------------------------------------------------+

//| Lots or risk in percent for a deal from a free margin            |

//+------------------------------------------------------------------+

bool LotsOrRisk(const double lots,const double risk,const int digits_adjust)

  {

   if(lots<0.0 && risk<0.0)

     {

      Print(__FUNCTION__,", ERROR: Parameter (\"lots\" or \"risk\") can't be less than zero");

      return(false);

     }

   if(lots==0.0 && risk==0.0)

     {

      Print(__FUNCTION__,", ERROR: Trade is impossible: You have set \"lots\" == 0.0 and \"risk\" == 0.0");

      return(false);

     }

   if(lots>0.0 && risk>0.0)

     {

      Print(__FUNCTION__,", ERROR: Trade is impossible: You have set \"lots\" > 0.0 and \"risk\" > 0.0");

      return(false);

     }

   if(lots>0.0)

     {

      string err_text="";

      if(!CheckVolumeValue(lots,err_text))

        {

         Print(__FUNCTION__,", ERROR: ",err_text);

         return(false);

        }

     }

   else if(risk>0.0)

     {

      if(m_money!=NULL)

         delete m_money;

      m_money=new CMoneyFixedMargin;

      if(m_money!=NULL)

        {

         if(!m_money.Init(GetPointer(m_symbol),Period(),m_symbol.Point()*digits_adjust))

            return(INIT_FAILED);

         m_money.Percent(risk);

        }

      else

        {

         Print(__FUNCTION__,", ERROR: Object CMoneyFixedMargin is NULL");

         return(INIT_FAILED);

        }

     }

//---

   return(true);

  }

//+------------------------------------------------------------------+ 

//| Create the horizontal line                                       | 

//+------------------------------------------------------------------+ 

bool HLineCreate(const long            chart_ID=0,        // chart's ID 

                 const string          name="HLine",      // line name 

                 const int             sub_window=0,      // subwindow index 

                 double                price=0,           // line price 

                 const color           clr=clrRed,        // line color 

                 const ENUM_LINE_STYLE style=STYLE_SOLID, // line style 

                 const int             width=1,           // line width 

                 const bool            back=false,        // in the background 

                 const bool            selection=false,   // highlight to move 

                 const bool            hidden=true,       // hidden in the object list 

                 const long            z_order=0)         // priority for mouse click 

  {

//--- if the price is not set, set it at the current Bid price level 

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- reset the error value 

   ResetLastError();

//--- create a horizontal line 

   if(!ObjectCreate(chart_ID,name,OBJ_HLINE,sub_window,0,price))

     {

      Print(__FUNCTION__,

            ": failed to create a horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- set line color 

   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);

//--- set line display style 

   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);

//--- set line width 

   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);

//--- display in the foreground (false) or background (true) 

   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);

//--- enable (true) or disable (false) the mode of moving the line by mouse 

//--- when creating a graphical object using ObjectCreate function, the object cannot be 

//--- highlighted and moved by default. Inside this method, selection parameter 

//--- is true by default making it possible to highlight and move the object 

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);

//--- hide (true) or display (false) graphical object name in the object list 

   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);

//--- set the priority for receiving the event of a mouse click in the chart 

   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);

//--- successful execution 

   return(true);

  }

//+------------------------------------------------------------------+ 

//| Move horizontal line                                             | 

//+------------------------------------------------------------------+ 

bool HLineMove(const long   chart_ID=0,   // chart's ID 

               const string name="HLine", // line name 

               double       price=0)      // line price 

  {

//--- if the line price is not set, move it to the current Bid price level 

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- reset the error value 

   ResetLastError();

//--- move a horizontal line 

   if(!ObjectMove(chart_ID,name,0,0,price))

     {

      Print(__FUNCTION__,

            ": failed to move the horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution 

   return(true);

  }

//+------------------------------------------------------------------+ 

//| Delete a horizontal line                                         | 

//+------------------------------------------------------------------+ 

bool HLineDelete(const long   chart_ID=0,   // chart's ID 

                 const string name="HLine") // line name 

  {

//--- reset the error value 

   ResetLastError();

//--- delete a horizontal line 

   if(!ObjectDelete(chart_ID,name))

     {

      Print(__FUNCTION__,

            ": failed to delete a horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution 

   return(true);

  }

//+------------------------------------------------------------------+

//| Trailing                                                         |

//+------------------------------------------------------------------+

void Trailing()

  {

   if(InpTrailingStop==0)

      return;

   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions

      if(m_position.SelectByIndex(i))

         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               if(m_position.PriceCurrent()-m_position.PriceOpen()>ExtTrailingStop+ExtTrailingStep)

                  if(m_position.StopLoss()<m_position.PriceCurrent()-(ExtTrailingStop+ExtTrailingStep))

                    {

                     if(!m_trade.PositionModify(m_position.Ticket(),

                        m_symbol.NormalizePrice(m_position.PriceCurrent()-ExtTrailingStop),

                        m_position.TakeProfit()))

                        Print("Modify ",m_position.Ticket(),

                              " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),

                              ", description of result: ",m_trade.ResultRetcodeDescription());

                     RefreshRates();

                     m_position.SelectByIndex(i);

                     PrintResultModify(m_trade,m_symbol,m_position);

                     continue;

                    }

              }

            else

              {

               if(m_position.PriceOpen()-m_position.PriceCurrent()>ExtTrailingStop+ExtTrailingStep)

                  if((m_position.StopLoss()>(m_position.PriceCurrent()+(ExtTrailingStop+ExtTrailingStep))) || 

                     (m_position.StopLoss()==0))

                    {

                     if(!m_trade.PositionModify(m_position.Ticket(),

                        m_symbol.NormalizePrice(m_position.PriceCurrent()+ExtTrailingStop),

                        m_position.TakeProfit()))

                        Print("Modify ",m_position.Ticket(),

                              " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),

                              ", description of result: ",m_trade.ResultRetcodeDescription());

                     RefreshRates();

                     m_position.SelectByIndex(i);

                     PrintResultModify(m_trade,m_symbol,m_position);

                    }

              }



           }

  }

//+------------------------------------------------------------------+

//| Print CTrade result                                              |

//+------------------------------------------------------------------+

void PrintResultModify(CTrade &trade,CSymbolInfo &symbol,CPositionInfo &position)

  {

   Print("Code of request result: "+IntegerToString(trade.ResultRetcode()));

   Print("code of request result as a string: "+trade.ResultRetcodeDescription());

   Print("Deal ticket: "+IntegerToString(trade.ResultDeal()));

   Print("Order ticket: "+IntegerToString(trade.ResultOrder()));

   Print("Volume of deal or order: "+DoubleToString(trade.ResultVolume(),2));

   Print("Price, confirmed by broker: "+DoubleToString(trade.ResultPrice(),symbol.Digits()));

   Print("Current bid price: "+DoubleToString(symbol.Bid(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultBid(),symbol.Digits()));

   Print("Current ask price: "+DoubleToString(symbol.Ask(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultAsk(),symbol.Digits()));

   Print("Broker comment: "+trade.ResultComment());

   Print("Price of position opening: "+DoubleToString(position.PriceOpen(),symbol.Digits()));

   Print("Price of position's Stop Loss: "+DoubleToString(position.StopLoss(),symbol.Digits()));

   Print("Price of position's Take Profit: "+DoubleToString(position.TakeProfit(),symbol.Digits()));

   Print("Current price by position: "+DoubleToString(position.PriceCurrent(),symbol.Digits()));

  }

//+------------------------------------------------------------------+

//| Search for indicator extremums                                   |

//+------------------------------------------------------------------+

bool SearchZigZagExtremums(const int count,double &array_results[])

  {

   if(!ArrayIsDynamic(array_results))

     {

      Print("This a no dynamic array!");

      return(false);

     }

   ArrayFree(array_results);

   ArrayResize(array_results,count);

   ArraySetAsSeries(array_results,true);

   int      buffer_num=0;           // indicator buffer number 

   double   arr_buffer[];

   ArraySetAsSeries(arr_buffer,true);

//--- reset error code 

   ResetLastError();

//--- fill a part of the iCustom array with values from the indicator buffer

   int copied=CopyBuffer(handle_iCustom,buffer_num,0,100,arr_buffer);

   if(copied<0)

     {

      //--- if the copying fails, tell the error code 

      PrintFormat("Failed to copy data from the iCustom indicator, error code %d",GetLastError());

      //--- quit with zero result - it means that the indicator is considered as not calculated 

      return(false);

     }

   int elements=0;

   for(int i=0;i<copied;i++)

     {

      if(arr_buffer[i]!=0)

        {

         array_results[elements]=arr_buffer[i];

         elements++;

         if(elements==count)

            break;

        }

     }

   if(elements==count)

      return(true);

//---

   return(false);

  }

//+------------------------------------------------------------------+

//| GetFibo                                                          |

//+------------------------------------------------------------------+

double GetFibo(const ENUM_FIBO fibo)

  {

   double result=0;;

   switch(fibo)

     {

      case level_0_0:   result= 0.0;   break;

      case level_23_6:  result= 23.6;  break;

      case level_38_2:  result= 38.2;  break;

      case level_50_0:  result= 50.0;  break;

      case level_61_8:  result= 61.8;  break;

      case level_100_0: result= 100.0; break;

      case level_161_8: result= 161.8; break;

      case level_261_8: result= 261.8; break;

      case level_423_6: result= 423.6; break;

     }

//---

   return(result);

  }

//+------------------------------------------------------------------+

//| Is position exists                                               |

//+------------------------------------------------------------------+

bool IsPositionExists(void)

  {

   for(int i=PositionsTotal()-1;i>=0;i--)

      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties

         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)

            return(true);

//---

   return(false);

  }

//+------------------------------------------------------------------+

//| Delete all pending orders                                        |

//+------------------------------------------------------------------+

void DeleteAllPendingOrders(void)

  {

   for(int i=OrdersTotal()-1;i>=0;i--) // returns the number of current orders

      if(m_order.SelectByIndex(i))     // selects the pending order by index for further access to its properties

         if(m_order.Symbol()==m_symbol.Name() && m_order.Magic()==m_magic)

            m_trade.OrderDelete(m_order.Ticket());

  }

//+------------------------------------------------------------------+

//| Is pendinf orders exists                                         |

//+------------------------------------------------------------------+

bool IsPendingOrdersExists(void)

  {

   for(int i=OrdersTotal()-1;i>=0;i--) // returns the number of current orders

      if(m_order.SelectByIndex(i))     // selects the pending order by index for further access to its properties

         if(m_order.Symbol()==m_symbol.Name() && m_order.Magic()==m_magic)

            return(true);

//---

   return(false);

  }

//+------------------------------------------------------------------+

//| Calculate all pending orders for symbol                          |

//+------------------------------------------------------------------+

void CalculateAllPendingOrders(int &count_buy_stop,ulong &ticket_buy_stop,

                               int &count_sell_stop,ulong &ticket_sell_stop)

  {

   for(int i=OrdersTotal()-1;i>=0;i--) // returns the number of current orders

      if(m_order.SelectByIndex(i))     // selects the pending order by index for further access to its properties

         if(m_order.Symbol()==m_symbol.Name() && m_order.Magic()==m_magic)

           {

            if(m_order.OrderType()==ORDER_TYPE_BUY_STOP)

              {

               count_buy_stop++;

               ticket_buy_stop=m_order.Ticket();

              }

            if(m_order.OrderType()==ORDER_TYPE_SELL_STOP)

              {

               count_sell_stop++;

               ticket_sell_stop=m_order.Ticket();

              }

           }

//---

  }

//+------------------------------------------------------------------+

//| Pending order of Buy Stop                                        |

//+------------------------------------------------------------------+

void PendingBuyStop(double price,double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);



   double check_open_long_lot=0.0;

   if(Risk>0.0)

     {

      check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),sl);

      Print("sl=",DoubleToString(sl,m_symbol.Digits()),

            ", CheckOpenLong: ",DoubleToString(check_open_long_lot,2),

            ", Balance: ",    DoubleToString(m_account.Balance(),2),

            ", Equity: ",     DoubleToString(m_account.Equity(),2),

            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));

      if(check_open_long_lot==0.0)

        {

         Print(__FUNCTION__,", ERROR: method CheckOpenLong returned the value of \"0.0\"");

         return;

        }

     }

   else

      check_open_long_lot=InpLots;

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)

   double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_long_lot,m_symbol.Ask(),ORDER_TYPE_BUY);



   if(check_volume_lot!=0.0)

     {

      if(check_volume_lot>=check_open_long_lot)

        {

         if(m_trade.BuyStop(check_open_long_lot,m_symbol.NormalizePrice(price),

            m_symbol.Name(),m_symbol.NormalizePrice(sl),m_symbol.NormalizePrice(tp)))

           {

            if(m_trade.ResultOrder()==0)

              {

               Print("#1 Buy Stop -> false. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResultTrade(m_trade,m_symbol);

              }

            else

              {

               Print("#2 Buy Stop -> true. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResultTrade(m_trade,m_symbol);

              }

           }

         else

           {

            Print("#3 Buy Stop -> false. Result Retcode: ",m_trade.ResultRetcode(),

                  ", description of result: ",m_trade.ResultRetcodeDescription());

            PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

         string text="";

         if(Risk>0.0)

            text="< method CheckOpenLong ("+DoubleToString(check_open_long_lot,2)+")";

         else

            text="< Lots ("+DoubleToString(InpLots,2)+")";

         Print(__FUNCTION__,", ERROR: method CheckVolume (",DoubleToString(check_volume_lot,2),") ",

               text);

         return;

        }

     }

   else

     {

      Print(__FUNCTION__,", ERROR: method CheckVolume returned the value of \"0.0\"");

      return;

     }

//---

  }

//+------------------------------------------------------------------+

//| Pending order of Sell Stop                                       |

//+------------------------------------------------------------------+

void PendingSellStop(double price,double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);



   double check_open_short_lot=0.0;

   if(Risk>0.0)

     {

      check_open_short_lot=m_money.CheckOpenShort(m_symbol.Bid(),sl);

      Print("sl=",DoubleToString(sl,m_symbol.Digits()),

            ", CheckOpenLong: ",DoubleToString(check_open_short_lot,2),

            ", Balance: ",    DoubleToString(m_account.Balance(),2),

            ", Equity: ",     DoubleToString(m_account.Equity(),2),

            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));

      if(check_open_short_lot==0.0)

        {

         Print(__FUNCTION__,", ERROR: method CheckOpenShort returned the value of \"0.0\"");

         return;

        }

     }

   else

      check_open_short_lot=InpLots;

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)

   double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_short_lot,m_symbol.Bid(),ORDER_TYPE_SELL);



   if(check_volume_lot!=0.0)

     {

      if(check_volume_lot>=check_open_short_lot)

        {

         if(m_trade.SellStop(check_open_short_lot,m_symbol.NormalizePrice(price),

            m_symbol.Name(),m_symbol.NormalizePrice(sl),m_symbol.NormalizePrice(tp)))

           {

            if(m_trade.ResultOrder()==0)

              {

               Print("#1 Sell Stop -> false. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResultTrade(m_trade,m_symbol);

              }

            else

              {

               Print("#2 Sell Stop -> true. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResultTrade(m_trade,m_symbol);

              }

           }

         else

           {

            Print("#3 Sell Stop -> false. Result Retcode: ",m_trade.ResultRetcode(),

                  ", description of result: ",m_trade.ResultRetcodeDescription());

            PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

         string text="";

         if(Risk>0.0)

            text="< method CheckOpenShort ("+DoubleToString(check_open_short_lot,2)+")";

         else

            text="< Lots ("+DoubleToString(InpLots,2)+")";

         Print(__FUNCTION__,", ERROR: method CheckVolume (",DoubleToString(InpLots,2),") ",

               text);

         return;

        }

     }

   else

     {

      Print(__FUNCTION__,", ERROR: method CheckVolume returned the value of \"0.0\"");

      return;

     }

//---

  }

//+------------------------------------------------------------------+

//| Print CTrade result                                              |

//+------------------------------------------------------------------+

void PrintResultTrade(CTrade &trade,CSymbolInfo &symbol)

  {

   Print("Code of request result: "+IntegerToString(trade.ResultRetcode()));

   Print("code of request result as a string: "+trade.ResultRetcodeDescription());

   Print("Deal ticket: "+IntegerToString(trade.ResultDeal()));

   Print("Order ticket: "+IntegerToString(trade.ResultOrder()));

   Print("Volume of deal or order: "+DoubleToString(trade.ResultVolume(),2));

   Print("Price, confirmed by broker: "+DoubleToString(trade.ResultPrice(),symbol.Digits()));

   Print("Current bid price: "+DoubleToString(symbol.Bid(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultBid(),symbol.Digits()));

   Print("Current ask price: "+DoubleToString(symbol.Ask(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultAsk(),symbol.Digits()));

   Print("Broker comment: "+trade.ResultComment());

  }

//+------------------------------------------------------------------+

//| Compare doubles                                                  |

//+------------------------------------------------------------------+

bool CompareDoubles(double number1,double number2,int digits)

  {

   digits--;

   if(digits<0)

      digits=0;

   if(NormalizeDouble(number1-number2,digits)==0)

      return(true);

   else

      return(false);

  }

//+------------------------------------------------------------------+

Comments