Author: Copyright © 2018, Vladimir Karputov
Price Data Components
Series array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Orders Execution
Checks for the total of open orders
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
Absorption
ÿþ//+------------------------------------------------------------------+

//|                          Absorption(barabashkakvn's edition).mq5 |

//|                              Copyright © 2018, Vladimir Karputov |

//|                                           http://wmua.ru/slesar/ |

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

#property copyright "Copyright © 2018, Vladimir Karputov"

#property link      "http://wmua.ru/slesar/"

#property version   "1.002"

//---

#define MODE_LOW 1

#define MODE_HIGH 2

//---

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

#include <Trade\OrderInfo.mqh>

CPositionInfo  m_position;                   // trade position object

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol;                     // symbol info object

COrderInfo     m_order;                      // pending orders object

//--- input parameters

input double   InpLots              = 0.1;   // Lots

input ushort   InpTakeProfitBuy     = 10;    // Take Profit Buy

input ushort   InpTakeProfitSell    = 10;    // Take Profit Sell 

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

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

input ushort   InpIndent            = 1;     // Indent from high or low

input int      Max_Search           = 10;    // Number of bars to search for price extremes

input int      OrderExp             = 8;     // Expiration a pending order in hours

input ulong    MagicType1           = 11111; // Magic number for signal 1

input ulong    MagicType2           = 22222; // Magic number for signal 2

input ushort   InpBreakeven         = 1;     // Breakeven (in pips) ("0" -> parameter "Breakeven" is off)

input ushort   InpBreakevenProfit   = 10;    // Breakeven profit (in pips)

//---

ulong          m_magic=0;                    // magic number

ulong          m_slippage=10;                // slippage

//---



double         ExtTakeProfitBuy=0.0;

double         ExtTakeProfitSell=0.0;

double         ExtTrailingStop=0.0;

double         ExtTrailingStep=0.0;

double         ExtIndent=0.0;

double         ExtBreakeven=0.0;

double         ExtBreakevenProfit=0.0;



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

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

//| Expert initialization function                                   |

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

int OnInit()

  {

//---

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

     {

      Alert(__FUNCTION__," ERROR: Trailing is not possible: the parameter \"Trailing Step\" is zero!");

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(InpBreakeven!=0 && InpBreakevenProfit==0)

     {

      Alert(__FUNCTION__," ERROR: Breakeven is not possible: the parameter \"Breakeven profit\" is zero!");

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(InpBreakeven>=InpBreakevenProfit)

     {

      Alert(__FUNCTION__," ERROR: \"Breakeven\" can not be greater than or equal to \"Breakeven profit\"!");

      return(INIT_PARAMETERS_INCORRECT);

     }

//---

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

      return(INIT_FAILED);

   RefreshRates();



   string err_text="";

   if(!CheckVolumeValue(InpLots,err_text))

     {

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

      return(INIT_PARAMETERS_INCORRECT);

     }

//---

   m_trade.SetExpertMagicNumber(m_magic);

//---

   if(IsFillingTypeAllowed(SYMBOL_FILLING_FOK))

      m_trade.SetTypeFilling(ORDER_FILLING_FOK);

   else if(IsFillingTypeAllowed(SYMBOL_FILLING_IOC))

      m_trade.SetTypeFilling(ORDER_FILLING_IOC);

   else

      m_trade.SetTypeFilling(ORDER_FILLING_RETURN);

//---

   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;



   ExtTakeProfitBuy     = InpTakeProfitBuy   * m_adjusted_point;

   ExtTakeProfitSell    = InpTakeProfitSell  * m_adjusted_point;

   ExtTrailingStop      = InpTrailingStop    * m_adjusted_point;

   ExtTrailingStep      = InpTrailingStep    * m_adjusted_point;

   ExtIndent            = InpIndent          * m_adjusted_point;

   ExtBreakeven         = InpBreakeven       * m_adjusted_point;

   ExtBreakevenProfit   = InpBreakevenProfit * m_adjusted_point;

//---

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//---



  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

//---

   StopLossInBreakeven();

//--- Checking for orders and positions

   bool exist_pos1=false,  exist_ord1=false;

   bool exist_pos2=false,  exist_ord2=false;

   bool exist_pos3=false,  exist_ord3=false;

   ExistPositionsAndPendingOrders(exist_pos1,exist_ord1,MagicType1,

                                  exist_pos2,exist_ord2,MagicType2);

//--- Order placing

   int signal_1=0;   double high_1=0.0;   double low_1=0.0;

   int signal_2=0;   double high_2=0.0;   double low_2=0.0;

   if(!Signals(signal_1,high_1,low_1,signal_2,high_2,low_2))

      return;

   if(!exist_pos1 && !exist_ord1 && signal_1!=0)

     {

      double price= high_2 + ExtIndent;

      double sl   = low_2  - ExtIndent;

      double tp   = price  + ExtTakeProfitBuy;

      m_trade.SetExpertMagicNumber(MagicType1);

      if(m_trade.BuyStop(InpLots,price,m_symbol.Name(),m_symbol.NormalizePrice(sl),m_symbol.NormalizePrice(tp),ORDER_TIME_SPECIFIED,TimeCurrent()+3600*OrderExp,"signal 1"))

         Print("BUY_STOP - > true. ticket of order = ",m_trade.ResultOrder());

      else

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

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

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



      price= low_2  - ExtIndent;

      sl   = high_2 + ExtIndent;

      tp   = price  - ExtTakeProfitSell;

      m_trade.SetExpertMagicNumber(MagicType2);

      if(m_trade.SellStop(InpLots,price,m_symbol.Name(),m_symbol.NormalizePrice(sl),m_symbol.NormalizePrice(tp),ORDER_TIME_SPECIFIED,TimeCurrent()+3600*OrderExp,"signal 1"))

         Print("SELL_STOP - > true. ticket of order = ",m_trade.ResultOrder());

      else

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

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

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



      return;

     }



   if(!exist_pos2 && !exist_ord2 && signal_2!=0)

     {

      double price= high_1 + ExtIndent;

      double sl   = low_1  - ExtIndent;

      double tp   = price  + ExtTakeProfitBuy;

      m_trade.SetExpertMagicNumber(MagicType1);

      if(m_trade.BuyStop(InpLots,price,m_symbol.Name(),m_symbol.NormalizePrice(sl),m_symbol.NormalizePrice(tp),ORDER_TIME_SPECIFIED,TimeCurrent()+3600*OrderExp,"signal 2"))

         Print("BUY_STOP - > true. ticket of order = ",m_trade.ResultOrder());

      else

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

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

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



      price= low_1  - ExtIndent;

      sl   = high_1 + ExtIndent;

      tp   = price  - ExtTakeProfitSell;

      m_trade.SetExpertMagicNumber(MagicType2);

      if(m_trade.SellStop(InpLots,price,m_symbol.Name(),m_symbol.NormalizePrice(sl),m_symbol.NormalizePrice(tp),ORDER_TIME_SPECIFIED,TimeCurrent()+3600*OrderExp,"signal 2"))

         Print("SELL_STOP - > true. ticket of order = ",m_trade.ResultOrder());

      else

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

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

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



      return;

     }



   Trailing();

  }

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

//| TradeTransaction function                                        |

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

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result)

  {

//--- get transaction type as enumeration value 

   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;

//--- if transaction is result of addition of the transaction in history

   if(type==TRADE_TRANSACTION_DEAL_ADD)

     {

      long     deal_ticket       =0;

      long     deal_order        =0;

      long     deal_time         =0;

      long     deal_time_msc     =0;

      long     deal_type         =-1;

      long     deal_entry        =-1;

      long     deal_magic        =0;

      long     deal_reason       =-1;

      long     deal_position_id  =0;

      double   deal_volume       =0.0;

      double   deal_price        =0.0;

      double   deal_commission   =0.0;

      double   deal_swap         =0.0;

      double   deal_profit       =0.0;

      string   deal_symbol       ="";

      string   deal_comment      ="";

      string   deal_external_id  ="";

      if(HistoryDealSelect(trans.deal))

        {

         deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);

         deal_order        =HistoryDealGetInteger(trans.deal,DEAL_ORDER);

         deal_time         =HistoryDealGetInteger(trans.deal,DEAL_TIME);

         deal_time_msc     =HistoryDealGetInteger(trans.deal,DEAL_TIME_MSC);

         deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);

         deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);

         deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);

         deal_reason       =HistoryDealGetInteger(trans.deal,DEAL_REASON);

         deal_position_id  =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);



         deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);

         deal_price        =HistoryDealGetDouble(trans.deal,DEAL_PRICE);

         deal_commission   =HistoryDealGetDouble(trans.deal,DEAL_COMMISSION);

         deal_swap         =HistoryDealGetDouble(trans.deal,DEAL_SWAP);

         deal_profit       =HistoryDealGetDouble(trans.deal,DEAL_PROFIT);



         deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);

         deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);

         deal_external_id  =HistoryDealGetString(trans.deal,DEAL_EXTERNAL_ID);

        }

      else

         return;

      if(deal_reason!=-1)

         DebugBreak();

      if(deal_symbol==m_symbol.Name() && (deal_magic==MagicType1 || deal_magic==MagicType2))

         if(deal_entry==DEAL_ENTRY_IN)

           {

            if(deal_type==DEAL_TYPE_BUY)

               DeleteOrders(ORDER_TYPE_SELL_STOP);

            else if(deal_type==DEAL_TYPE_SELL)

               DeleteOrders(ORDER_TYPE_BUY_STOP);

           }

     }



  }

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

//| 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 order 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();

   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);

   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);

  }

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

//| Checks if the specified filling mode is allowed                  | 

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

bool IsFillingTypeAllowed(int fill_type)

  {

//--- Obtain the value of the property that describes allowed filling modes 

   int filling=m_symbol.TradeFillFlags();

//--- Return true, if mode fill_type is allowed 

   return((filling & fill_type)==fill_type);

  }

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

//| Stop Loss in a breakeven                                         |

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

void StopLossInBreakeven()

  {

   if(InpBreakeven==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()==MagicType1 || m_position.Magic()==MagicType2))

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               if(m_position.StopLoss()<m_position.PriceOpen() || m_position.StopLoss()==0.0)

                  if(m_position.PriceCurrent()-m_position.PriceOpen()>ExtBreakevenProfit)

                    {

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

                        m_symbol.NormalizePrice(m_position.PriceOpen()+ExtBreakeven),

                        m_position.TakeProfit()))

                        Print("Breakeven BUY ",m_position.Ticket(),

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

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

                    }

              }

            else

              {

               double pos_sl=m_position.StopLoss();

               double pos_po=m_position.PriceOpen();

               double pos_pc=m_position.PriceCurrent();

               if(m_position.StopLoss()>m_position.PriceOpen() || m_position.StopLoss()==0.0)

                  if(m_position.PriceOpen()-m_position.PriceCurrent()>ExtBreakevenProfit)

                    {

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

                        m_symbol.NormalizePrice(m_position.PriceOpen()-ExtBreakeven),

                        m_position.TakeProfit()))

                        Print("Breakeven SELL ",m_position.Ticket(),

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

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

                    }

              }



           }

  }

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

//| 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);

  }

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

//| Exist positions and pending orders                               |

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

void ExistPositionsAndPendingOrders(bool &pos_1,bool &ord_1,const ulong magic_1,

                                    bool &pos_2,bool &ord_2,const ulong magic_2)

  {

//--- initialization

   pos_1=false;   ord_1=false;

   pos_2=false;   ord_2=false;

//---

   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())

           {

            if(m_position.Magic()==magic_1)

               pos_1=true;

            if(m_position.Magic()==magic_2)

               pos_2=true;

            //---

            if(pos_1 && pos_2)

               break;

           }

//---

   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())

           {

            if(m_order.Magic()==magic_1)

               ord_1=true;

            if(m_order.Magic()==magic_2)

               ord_2=true;

            //---

            if(ord_1 && ord_2)

               break;

           }

  }

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

//| Signals                                                          |

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

bool Signals(int &signal_1,double &high_1,double &low_1,int &signal_2,double &high_2,double &low_2)

  {

   signal_1=0; high_1=0.0; low_1=0.0;

   signal_2=0; high_2=0.0; low_2=0.0;



   int lowest=iLowest(m_symbol.Name(),Period(),MODE_LOW,Max_Search,0);

   if(lowest==-1)

      return(false);



   int highest=iHighest(m_symbol.Name(),Period(),MODE_HIGH,Max_Search,0);

   if(highest==-1)

      return(false);



   high_2=iHigh(2);

   if(high_2==0.0)

      return(false);



   high_1=iHigh(1);

   if(high_1==0.0)

      return(false);



   low_2=iLow(2);

   if(low_2==0.0)

      return(false);



   low_1=iLow(1);

   if(low_1==0.0)

      return(false);



//--- pattern Absorption in bar #2

   if(lowest==2 && high_2>high_1 && low_2<low_1)

     {

      signal_1=1;

     }

   else if(highest==2 && high_2>high_1 && low_2<low_1)

     {

      signal_1=-1;

     }

   else

      signal_1=0;

//--- pattern Absorption in bar #1

   if(lowest==1 && high_1>high_2 && low_1<low_2)

     {

      signal_2=1;

     }

   else if(highest==1 && high_1>high_2 && low_1<low_2)

     {

      signal_2=-1;

     }

   else

      signal_2=0;

//---

   return(true);

  }

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

//| Lowest                                                           |

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

int iLowest(string symbol,

            ENUM_TIMEFRAMES timeframe,

            int type,

            int count=WHOLE_ARRAY,

            int start=0)

  {

   if(symbol==NULL)

      symbol=m_symbol.Name();

   if(timeframe==0)

      timeframe=Period();

   if(start<0)

      return(-1);

   if(count<=0)

      count=Bars(symbol,timeframe);

   if(type==MODE_LOW)

     {

      double Low[];

      ArraySetAsSeries(Low,true);

      int copied=CopyLow(symbol,timeframe,start,count,Low);

      if(copied==-1 || copied!=count)

         return(-1);

      return(ArrayMinimum(Low));

     }

//---

   return(-1);

  }

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

//| Highest                                                          |

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

int iHighest(string symbol,

             ENUM_TIMEFRAMES timeframe,

             int type,

             int count=WHOLE_ARRAY,

             int start=0)

  {

   if(symbol==NULL)

      symbol=m_symbol.Name();

   if(timeframe==0)

      timeframe=Period();

   if(start<0)

      return(-1);

   if(count<=0)

      count=Bars(symbol,timeframe);

   if(type==MODE_HIGH)

     {

      double High[];

      ArraySetAsSeries(High,true);

      int copied=CopyHigh(symbol,timeframe,start,count,High);

      if(copied==-1 || copied!=count)

         return(-1);

      return(ArrayMinimum(High));

     }

//---

   return(-1);

  }

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

//| Get the High for specified bar index                             | 

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

double iHigh(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)

  {

   if(symbol==NULL)

      symbol=m_symbol.Name();

   if(timeframe==0)

      timeframe=Period();

   double High[1];

   double high=0.0;

   int copied=CopyHigh(symbol,timeframe,index,1,High);

   if(copied>0)

      high=High[0];

   return(high);

  }

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

//| Get Low for specified bar index                                  | 

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

double iLow(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)

  {

   if(symbol==NULL)

      symbol=m_symbol.Name();

   if(timeframe==0)

      timeframe=Period();

   double Low[1];

   double low=0.0;

   int copied=CopyLow(symbol,timeframe,index,1,Low);

   if(copied>0)

      low=Low[0];

   return(low);

  }

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

//| Delete Orders                                                    |

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

void DeleteOrders(const ENUM_ORDER_TYPE order_type)

  {

   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()==MagicType1 || m_order.Magic()==MagicType2))

            if(m_order.OrderType()==order_type)

               m_trade.OrderDelete(m_order.Ticket());

  }

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

//| 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()==MagicType1 || m_position.Magic()==MagicType2))

           {

            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());

                    }

              }

            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());

                    }

              }



           }

  }

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

Comments