My Trailing stop does not work (MQL5)

Ahmed Abd El Aziz  
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2

#property indicator_type1 DRAW_ARROW
#property indicator_width1 3
#property indicator_color1 0xFF901E
#property indicator_label1 "Buy"

#property indicator_type2 DRAW_ARROW
#property indicator_width2 3
#property indicator_color2 0xFF00FF
#property indicator_label2 "Sell"

//--- indicator buffers
double Buffer1[];
double Buffer2[];

datetime time_alert; //used when sending alert
input bool Send_Email = true;
input bool Audible_Alerts = true;
input bool Push_Notifications = true;
double myPoint; //initialized in OnInit
double Close[];
double Open[];
int MA_handle;
double MA[];
int WPR_handle;
double WPR[];
int MA_handle2;
double MA2[];
int ADX_handle;
double ADX_PlusDI[];
int MA_handle3;
double MA3[];
double Low[];
double ADX_MinusDI[];
double High[];

void myAlert(string type, string message)
  {
   int handle;
   if(type == "print")
      Print(message);
   else if(type == "error")
     {
      Print(type+" | Test @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
   else if(type == "order")
     {
     }
   else if(type == "modify")
     {
     }
   else if(type == "indicator")
     {
      Print(type+" | Test @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      if(Audible_Alerts) Alert(type+" | Test @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      if(Send_Email) SendMail("Test", type+" | Test @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      handle = FileOpen("Test.txt", FILE_TXT|FILE_READ|FILE_WRITE|FILE_SHARE_READ|FILE_SHARE_WRITE, ';');
      if(handle != INVALID_HANDLE)
        {
         FileSeek(handle, 0, SEEK_END);
         FileWrite(handle, type+" | Test @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
         FileClose(handle);
        }
      if(Push_Notifications) SendNotification(type+" | Test @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
  }

double CandlestickBodyLength(ENUM_TIMEFRAMES timeframe, int shift)
  {
   double cOpen[];
   CopyOpen(Symbol(), timeframe, shift, 1, cOpen);
   ArraySetAsSeries(cOpen, true);
   double cClose[];
   CopyClose(Symbol(), timeframe, shift, 1, cClose);
   ArraySetAsSeries(cClose, true);
   return(MathAbs(cOpen[0] - cClose[0]));
  }

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {   
   SetIndexBuffer(0, Buffer1);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(0, PLOT_ARROW, 233);
   SetIndexBuffer(1, Buffer2);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(1, PLOT_ARROW, 234);
   //initialize myPoint
   myPoint = Point();
   if(Digits() == 5 || Digits() == 2)
     {
      myPoint *= 10;
     }
   MA_handle = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_EMA, PRICE_CLOSE);
   if(MA_handle < 0)
     {
      Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle2 = iMA(NULL, PERIOD_CURRENT, 40, 0, MODE_EMA, PRICE_CLOSE);
   if(MA_handle2 < 0)
     {
      Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   ADX_handle = iADX(NULL, PERIOD_CURRENT, 5);
   if(ADX_handle < 0)
     {
      Print("The creation of iADX has failed: ADX_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle3 = iMA(NULL, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE);
   if(MA_handle3 < 0)
     {
      Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   WPR_handle = iWPR(NULL, PERIOD_CURRENT, 14);
   if(WPR_handle < 0)
     {
      Print("The creation of iWPR has failed: WPR_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
   int limit = rates_total - prev_calculated;
   //--- counting from 0 to rates_total
   ArraySetAsSeries(Buffer1, true);
   ArraySetAsSeries(Buffer2, true);
   //--- initial zero
   if(prev_calculated < 1)
     {
      ArrayInitialize(Buffer1, EMPTY_VALUE);
      ArrayInitialize(Buffer2, EMPTY_VALUE);
     }
   else
      limit++;
   datetime Time[];
   
   if(CopyClose(Symbol(), PERIOD_CURRENT, 0, rates_total, Close) <= 0) return(rates_total);
   ArraySetAsSeries(Close, true);
   if(CopyOpen(Symbol(), PERIOD_CURRENT, 0, rates_total, Open) <= 0) return(rates_total);
   ArraySetAsSeries(Open, true);
   if(BarsCalculated(MA_handle) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
   ArraySetAsSeries(MA, true);
   if(BarsCalculated(MA_handle2) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);
   ArraySetAsSeries(MA2, true);
   if(BarsCalculated(ADX_handle) <= 0) 
      return(0);
   if(CopyBuffer(ADX_handle, PLUSDI_LINE, 0, rates_total, ADX_PlusDI) <= 0) return(rates_total);
   ArraySetAsSeries(ADX_PlusDI, true);
   if(BarsCalculated(MA_handle3) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) <= 0) return(rates_total);
   ArraySetAsSeries(MA3, true);
   if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
   ArraySetAsSeries(Low, true);
   if(BarsCalculated(ADX_handle) <= 0) 
      return(0);
   if(CopyBuffer(ADX_handle, MINUSDI_LINE, 0, rates_total, ADX_MinusDI) <= 0) return(rates_total);
   ArraySetAsSeries(ADX_MinusDI, true);
   if(BarsCalculated(WPR_handle) <= 0) 
      return(0);
   if(CopyBuffer(WPR_handle, 0, 0, rates_total, WPR) <= 0) return(rates_total);
   ArraySetAsSeries(WPR, true);
   if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
   ArraySetAsSeries(High, true);
   if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total);
   ArraySetAsSeries(Time, true);
   //--- main loop
   for(int i = limit-1; i >= 0; i--)
     {
      if (i >= MathMin(464444-1, rates_total-1-50)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
      
      //Indicator Buffer 1
      if(Close[i] > Open[i]
      && Close[i] > MA[i]
      && Close[i] > MA2[i]
      && ADX_PlusDI[i] > 25
      && ADX_PlusDI[i] < 50
      && ADX_MinusDI[i] < 25
      && Low[i] < MA2[i]
      && (Close[i]-Open[i]) < +1200 * myPoint
      && (Close[i]-Open[i]) > +350 * myPoint
      && MA2[i]>MA[i]
      && (MA2[i]-MA[i])>+200 * myPoint
      && (Close[i]-MA2[i])<=+900 * myPoint
      )
        {
         Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer1[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 2
      if(Close[i] < Open[i]
      && Close[i] < MA[i]
      && Close[i] < MA2[i]
      && ADX_MinusDI[i] > 25
      && ADX_MinusDI[i] < 50
      && ADX_PlusDI[i] < 25
      && High[i] > MA2[i]
      && (Open[i]-Close[i]) < +1200 * myPoint
      && (Open[i]-Close[i]) > +350 * myPoint
      && MA2[i]<MA[i]
      && (MA[i]-MA2[i])>+200 * myPoint
      && (MA2[i]-Close[i])<=+900 * myPoint
      )
        {
         Buffer2[i] = High[i]; //Set indicator value at Candlestick High
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer2[i] = EMPTY_VALUE;
        }
     }
   return(rates_total);
  }


And this is my expert code:


input   int             InpTakeProfitPts                =       0;
input   int             InpStopLossPts                  =       0;
input int      TrailingStop         =  50;
//
//      Standard inputs
//
input   double  InpOrderSize                    =       0.10;                   //      Order size
input   string  InpTradeComment         =       __FILE__;       //      Trade comment
input   int             InpMagicNumber                  =       2000001;                //      Magic number
input int RangeS=121;
input int RangeT=121;
input double Goal=3.5;
input double Spread = 35;

double                  TakeProfit;
double                  StopLoss;
bool                            CloseOpposite;
const string IndicatorName="Test []";
const int Handle_Buy = 0;
const int Handle_Sell = 1;
int Handle;
double BufferBuy[3];
double BufferSell[3];
datetime lastTime = 0;
//
//      Use CTrade, easier than doing our own coding
//
#include <Trade\Trade.mqh>
CTrade  *Trade;

int OnInit() {

        //
        //      Create a pointer to a ctrade object
        //
        Trade   =       new CTrade();
        Trade.SetExpertMagicNumber(InpMagicNumber);
        Handle=iCustom(Symbol(),Period(),IndicatorName);

if(Handle==INVALID_HANDLE)
     {
      PrintFormat("Failed",GetLastError());
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }
  
void OnDeinit(const int reason) {
IndicatorRelease(Handle);

}
void OnTick() 
{
   int cnt_B = CopyBuffer(Handle,Handle_Buy,0,3,BufferBuy);
   int cnt_S = CopyBuffer(Handle,Handle_Sell,0,3,BufferSell);
       
   double Previous_Candle_Buy = BufferBuy[1];
   double Current_Candle_Buy = BufferBuy[0];
   
   double Previous_Candle_Sell = BufferSell[1];
   double Current_Candle_Sell = BufferSell[0];
   
   
   bool buyCondition = false;
   bool sellCondition = false;
   
   if(lastTime != iTime(Symbol(), 0, 1)) 
  {
      lastTime = iTime(Symbol(), 0, 1);
  }
  else
  {
      return;
  }
   if( Previous_Candle_Buy ==iLow(_Symbol, PERIOD_CURRENT,1)) { buyCondition = true;}
   if( Previous_Candle_Sell ==iHigh(_Symbol, PERIOD_CURRENT,1)) { sellCondition = true;}

        double  point   =       SymbolInfoDouble(Symbol(), SYMBOL_POINT);
        TakeProfit              =       InpTakeProfitPts * point;
        StopLoss                        =       InpStopLossPts * point;

        CloseOpposite   =       false;


        if (buyCondition) {
                if (CloseOpposite) CloseAll(POSITION_TYPE_SELL);
                OrderOpen(ORDER_TYPE_BUY, StopLoss, TakeProfit);
        } else
        if (sellCondition) {
                if (CloseOpposite) CloseAll(POSITION_TYPE_BUY);
                OrderOpen(ORDER_TYPE_SELL, StopLoss, TakeProfit);
        }
        
        //
        //      Save any information for next time
        //

        return;
        
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Highest(string symbol,ENUM_TIMEFRAMES timeframe,int count=WHOLE_ARRAY,int start=0)
{
   double highest=0;
   double High[];
   ArraySetAsSeries(High,true);
   int copied=CopyHigh(symbol,timeframe,start,count,High) ;
   int index=ArrayMaximum(High,0,count)+start;
   if(copied>0 && index<copied) highest=High[index];
   return(highest);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Lowest(string symbol,ENUM_TIMEFRAMES timeframe,int count=WHOLE_ARRAY,int start=0)
{
   double lowest=0;
   double Low[];
   ArraySetAsSeries(Low,true);
   int copied=CopyLow(symbol,timeframe,start,count,Low);
   int index=ArrayMinimum(Low,0,count)+start;
   if(copied>0 && index<copied) lowest=Low[index];
   return(lowest);
}


//
//      true/false has the bar changed
//
bool    NewBar() {

        static datetime priorTime       =       0;
        datetime                                currentTime     =       iTime(Symbol(), Period(), 0);
        bool                                    result          =       (currentTime!=priorTime);
        priorTime                                                       =       currentTime;
        return(result);
        
}

//
//      Close all trades of the specified type - for strategies that call for closing the opposite side
//
void    CloseAll(ENUM_POSITION_TYPE positionType) {

        int     cnt     =       PositionsTotal();
        for (int i = cnt-1; i>=0; i--) {
                ulong   ticket  =       PositionGetTicket(i);
                if (ticket>0) {
                        if (PositionGetString(POSITION_SYMBOL)==Symbol() && PositionGetInteger(POSITION_MAGIC)==InpMagicNumber && PositionGetInteger(POSITION_TYPE)==positionType) {
                                Trade.PositionClose(ticket);
                        }
                }
        }
        
}

//
//      Simple function to open a new order
//
int     OrderOpen(ENUM_ORDER_TYPE orderType, double stopLoss, double takeProfit) {

        double  openPrice;
        double  stopLossPrice;
        double  takeProfitPrice;
        
        //
        //      Calculate the open price, take profit and stop loss prices based on the order type
        //      
        double  point   =       SymbolInfoDouble(Symbol(), SYMBOL_POINT);
        if (orderType==ORDER_TYPE_BUY) {
                openPrice                       =       NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_ASK), Digits());
                stopLossPrice           = (((Lowest(Symbol() , _Period, RangeS, 0)))-(Spread*point));
                takeProfitPrice =(((((iClose(Symbol() ,PERIOD_CURRENT,1))-(Lowest(Symbol() , _Period, RangeT, 0)))*Goal)+(Lowest(Symbol() , _Period, RangeT, 0)))-(Spread*point));
                int     cnt     =       PositionsTotal();
                for (int i = cnt-1; i>=0; i--) {
                ulong   ticket  =       PositionGetTicket(i);
                if(TrailingStop>0)  
              {                 
               if(SymbolInfoDouble(_Symbol,SYMBOL_BID)-PositionGetDouble(POSITION_PRICE_OPEN)>point*TrailingStop)
                 {
                  if(PositionGetDouble(POSITION_SL)<SymbolInfoDouble(_Symbol,SYMBOL_BID)-point*TrailingStop)
                    {
                    Trade.PositionModify(ticket,SymbolInfoDouble(_Symbol,SYMBOL_BID)-point*TrailingStop,PositionGetDouble(POSITION_TP));
                     return (0);
                    }
                 }
              }
              }
        } else if (orderType==ORDER_TYPE_SELL) {
                openPrice                       =       NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_BID), Digits());
                stopLossPrice           = (((Highest(Symbol() , _Period, RangeS, 0)))+(Spread*point));
                takeProfitPrice =(((Highest(Symbol() , _Period, RangeT, 0))-(((Highest(Symbol() , _Period, RangeT, 0))-(iClose(Symbol() ,PERIOD_CURRENT,1)))*Goal))+(Spread*point));
                int     cnt     =       PositionsTotal();
                for (int i = cnt-1; i>=0; i--) {
                ulong   ticket  =       PositionGetTicket(i);
                if(TrailingStop>0)  
              {                 
               if(PositionGetDouble(POSITION_PRICE_OPEN)-SymbolInfoDouble(_Symbol,SYMBOL_ASK)>point*TrailingStop)
                 {
                  if(PositionGetDouble(POSITION_SL)>SymbolInfoDouble(_Symbol,SYMBOL_ASK)+point*TrailingStop)
                    {
                    Trade.PositionModify(ticket,SymbolInfoDouble(_Symbol,SYMBOL_ASK)+point*TrailingStop,PositionGetDouble(POSITION_TP));
                     return (0);
                    }
                 }
              }
              }
        } else {
                //      This function only works with type buy or sell
                return(-1);
        }

        Trade.PositionOpen(Symbol(), orderType, InpOrderSize, openPrice, stopLossPrice, takeProfitPrice, InpTradeComment);

        return((int)Trade.ResultOrder());
        
}
Ahmed Abd El Aziz  
What is wrong in my trailing stop code at my expert?
R4tna C  
Ahmed Abd El Aziz #:
What is wrong in my trailing stop code at my expert?

Can't say from what you have posted - put breakpoints just after the Trade.Position.Modify() calls and see what is written in the journal when it fails.

That should provide a clue 

William Roeder  
  1.    int cnt_B = CopyBuffer(Handle,Handle_Buy,0,3,BufferBuy);
       int cnt_S = CopyBuffer(Handle,Handle_Sell,0,3,BufferSell);
    You haven't set the arrays as-series before populating them.
  2. Why is the new bar code in the middle of OnTick, instead of being the first thing?
  3. Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?
              Code debugging - Developing programs - MetaEditor Help
              Error Handling and Logging in MQL5 - MQL5 Articles (2015)
              Tracing, Debugging and Structural Analysis of Source Code - MQL5 Articles (2011)
              Introduction to MQL5: How to write simple Expert Advisor and Custom Indicator - MQL5 Articles (2010)

Reason: