Coding Trailing Stop Loss in MQL5

 

Hey guys,

I am struggling with coding a trailing stop loss in my EA in MQL5.

Could anyone please help me? 

I would be extremely grateful.

Thanks in advance,

Martin

//+------------------------------------------------------------------+
//| MACD crossing the Signal line
//| WORKING ON Trailing Stop Loss 
//+------------------------------------------------------------------+

#include <Trade\Trade.mqh> // Get code from other places

//--- Input Variables (Accessible from MetaTrader 5)

input double   lot = 1;
input int      shortemaPeriods = 60;
input int      longemaPeriods = 240;
input int      signalemaPeriods = 20;
input int      slippage = 0;
input bool     useStopLoss = false;
input double   stopLossPips = 0;
input bool     useTakeProfit = false;
input double   takeProfitPips = 0;
input bool IsUseTrailingStop  = false;
input int TrailingStopDistance = 0;

//--- Service Variables (Only accessible from the MetaEditor)

CTrade myTradingControlPanel;
double MACDData[], shortemaData[], longemaData[], signalemaData[]; // You can declare multiple variables of the same data type in the same line.
int numberOfMACDData, numberOfLongemaData, numberofSignalemaData; 
int MACDControlPanel, longemaControlPanel, signalemaControlPanel;
int P;
double currentBid, currentAsk;
double stopLossPipsFinal, takeProfitPipsFinal, stopLevelPips;
double stopLossLevel, takeProfitLevel;
double macd1, macd2, shortema1, shortema2, longema1, longema2, signalema1, signalema2;

double trailing_stop_value;
//ulong array_tickets[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ArraySetAsSeries(MACDData,true);   // Setting up table/array for time series data
   ArraySetAsSeries(signalemaData,true);
      
   MACDControlPanel = iMA(_Symbol, _Period, longemaPeriods-shortemaPeriods, 0, MODE_EMA, PRICE_CLOSE);
   signalemaControlPanel = iMA (_Symbol, _Period, MACDControlPanel, 0, MODE_EMA, PRICE_CLOSE);
   
   if(_Digits == 5 || _Digits == 3 || _Digits == 1) P = 10;else P = 1; // To account for 5 digit brokers
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   IndicatorRelease(MACDControlPanel);
   IndicatorRelease(signalemaControlPanel);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   // -------------------- Collect most current data --------------------
   
   currentBid = SymbolInfoDouble(_Symbol,SYMBOL_BID); // Get latest Bid Price
   currentAsk = SymbolInfoDouble(_Symbol,SYMBOL_ASK); // Get latest Ask Price
   
   numberOfMACDData = CopyBuffer(MACDControlPanel, 0, 0, 3, MACDData);
   numberofSignalemaData = CopyBuffer (signalemaControlPanel, 0, 0, 3, signalemaData);
   
   macd1 = MACDData[1];
   macd2 = MACDData[2]; 
   signalema1 = signalemaData[1];
   signalema2 = signalemaData[2];
   
   // -------------------- Technical Requirements --------------------
      
   stopLevelPips = (double) (SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) + SymbolInfoInteger(_Symbol, SYMBOL_SPREAD)) / P; // Defining minimum StopLevel

   if (stopLossPips < stopLevelPips) 
      {
      stopLossPipsFinal = stopLevelPips;
      } 
   else
      {
      stopLossPipsFinal = stopLossPips;
      } 
      
   if (takeProfitPips < stopLevelPips) 
      {
      takeProfitPipsFinal = stopLevelPips;
      }
   else
      {
      takeProfitPipsFinal = takeProfitPips;
      }

      
  // -------------------- EXITS --------------------
   
   if(PositionSelect(_Symbol) == true) // We have an open position
      { 
      
      // --- Exit Rules (Long Trades) ---
      
      /*
      Exits:
      - Exit the long trade when MACD crosses signal line from top
      - Exit the short trade when MACD crosses the signal line from bottom
      */
      
      // TDL 3: Enter exit rule for long trades
      
      // --------------------------------------------------------- //
      
      if(macd2 < signalema2 && macd1 >= signalema1) // Rule to exit long trades
         
      // --------------------------------------------------------- //
         
         {
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) // If it is Buy position
            { 
            
            myTradingControlPanel.PositionClose(_Symbol); // Closes position related to this symbol
            
            if(myTradingControlPanel.ResultRetcode()==10008 || myTradingControlPanel.ResultRetcode()==10009) //Request is completed or order placed
               {
               Print("Exit rules: A close order has been successfully placed with Ticket#: ",myTradingControlPanel.ResultOrder());
               }
            else
               {
               Print("Exit rules: The close order request could not be completed.Error: ",GetLastError());
               ResetLastError();
               return;
               }
               
            }
         }
      
      // TDL 4: Enter exit rule for short trades
      
      // --------------------------------------------------------- //
      
      if(macd2 > signalema2 && macd1 <= signalema1) // Rule to exit short trades
         
      // --------------------------------------------------------- //  
       
         {
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) // If it is Sell position
            { 
            
            myTradingControlPanel.PositionClose(_Symbol); // Closes position related to this symbol
            
            if(myTradingControlPanel.ResultRetcode()==10008 || myTradingControlPanel.ResultRetcode()==10009) //Request is completed or order placed
               {
               Print("Exit rules: A close order has been successfully placed with Ticket#: ", myTradingControlPanel.ResultOrder());
               }
            else
               {
               Print("Exit rules: The close order request could not be completed. Error: ", GetLastError());
               ResetLastError();
               return;
               }
            }
         }
      
      }
   
   // -------------------- ENTRIES --------------------  
         
   if(PositionSelect(_Symbol) == false) // We have no open position
      { 
      
      // --- Entry Rules (Long Trades) ---
      
      /*
      Entries:
      - Enter a long trade when MACD crosses the signal line from bottom
      - Enter a short trade when MACD crosses signal line from top
      */
      
      // TDL 1: Enter entry rule for long trades
      
      // --------------------------------------------------------- //
      
      if(macd2 > signalema2 && macd1 <= signalema1) // Rule to enter long trades
      
      // --------------------------------------------------------- //
     
         {   
         
         if (useStopLoss) stopLossLevel = currentAsk - stopLossPipsFinal * _Point * P; else stopLossLevel = 0.0;
         if (useTakeProfit) takeProfitLevel = currentAsk + takeProfitPipsFinal * _Point * P; else takeProfitLevel = 0.0;
        
         myTradingControlPanel.PositionOpen(_Symbol, ORDER_TYPE_BUY, lot, currentAsk, stopLossLevel, takeProfitLevel, "Buy Trade. Magic Number #" + (string) myTradingControlPanel.RequestMagic()); // Open a Buy position
         
         if(myTradingControlPanel.ResultRetcode()==10008 || myTradingControlPanel.ResultRetcode()==10009) //Request is completed or order placed
            {
            Print("Entry rules: A Buy order has been successfully placed with Ticket#: ", myTradingControlPanel.ResultOrder());
            }
         else
            {
            Print("Entry rules: The Buy order request could not be completed. Error: ", GetLastError());
            ResetLastError();
            return;
            }
           
         }
         
      // --- Entry Rules (Short Trades) ---
      
      /*
      Exit:
      - Exit the long trade when MACD crosses the signal line from top
      - Exit the short trade when MACD crosses the signal line from bottom
      */
      
      // TDL 2: Enter entry rule for short trades
      
      // --------------------------------------------------------- //
      
      else if(macd2 < signalema2 && macd1 >= signalema1) // Rule to enter short trades
      
      // --------------------------------------------------------- //

         {   
         
         if (useStopLoss) stopLossLevel = currentBid + stopLossPipsFinal * _Point * P; else stopLossLevel = 0.0;
         if (useTakeProfit) takeProfitLevel = currentBid - takeProfitPipsFinal * _Point * P; else takeProfitLevel = 0.0;

         myTradingControlPanel.PositionOpen(_Symbol, ORDER_TYPE_SELL, lot, currentBid, stopLossLevel, takeProfitLevel, "Sell Trade. Magic Number #" + (string) myTradingControlPanel.RequestMagic()); // Open a Sell position
         
         if(myTradingControlPanel.ResultRetcode()==10008 || myTradingControlPanel.ResultRetcode()==10009) //Request is completed or order placed
            {
            Print("Entry rules: A Sell order has been successfully placed with Ticket#: ", myTradingControlPanel.ResultOrder());
            }
         else
            {
            Print("Entry rules: The Sell order request could not be completed.Error: ", GetLastError());
            ResetLastError();
            return;
            }
         
         } 
      
      }
   
//+------------------------------------------------------------------+
//| Trailing Stop Loss                                 |
//+------------------------------------------------------------------+
      
//      if (IsUseTrailingStop)

   if(!IsUseTrailingStop || TrailingStopDistance==0)
      return;
   //for(int i=0;i<ArraySize(arr_ticket);i++)
   {
    //   ulong ticket=arr_ticket[i];
    //   bool is_selected=PositionSelectByTicket(ticket);
    //   if(is_selected)
   //    {
          ENUM_POSITION_TYPE position_type=PositionGetInteger(POSITION_TYPE);
          double open_price=PositionGetDouble(POSITION_PRICE_OPEN);
          double current_stop_loss=PositionGetDouble(POSITION_SL);
          double local_stop_loss;
          double ask_price=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
          double bid_price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
          if(position_type==POSITION_TYPE_BUY)
          {
             if(bid_price-open_price>trailing_stop_value)
             {
                local_stop_loss=NormalizeDouble(bid_price-trailing_stop_value,Digits());
                if(current_stop_loss<local_stop_loss)
                {
                   myTradingControlPanel.PositionModify(_Symbol, local_stop_loss, takeProfitLevel)
                   //ext_trade.PositionModify(ticket,local_stop_loss,0);
                }
             }
          }
          else if(position_type==POSITION_TYPE_SELL)
          {
             if(open_price-ask_price>trailing_stop_value)
             {
                 local_stop_loss=NormalizeDouble(ask_price+trailing_stop_value,Digits());
                 if(current_stop_loss>local_stop_loss)
                 {
                    myTradingControlPanel.PositionModify(_Symbol,local_stop_loss, takeProfitLevel)
                    //ext_trade.PositionModify(ticket,local_stop_loss,0);
                 }
             
             }
          }
          
      // }
   }    
      
      
      
   }
Basic Principles - Trading Operations - MetaTrader 5
Basic Principles - Trading Operations - MetaTrader 5
  • www.metatrader5.com
is an instruction given to a broker to buy or sell a financial instrument. There are two main types of orders: Market and Pending. In addition, there are special Take Profit and Stop Loss levels. is the commercial exchange (buying or selling) of a financial security. Buying is executed at the demand price (Ask), and Sell is performed at the...
 

there is the position modfy function missing

 
Try the wizard 
 
amando:

there is the position modfy function missing

Where?

Tafadzwa Nyamwanza:
Try the wizard 

What's that?

 
the general procedure for a good trailing stops is :
  • count all open positions
  • skip unwanted positions (filter)
    some common filters :
    1. positions with specific magic number will be considered for setting a trailing stop
    2. positions that are in profit (or have reached at least %X of max profit) are considered
    3. positions that are open more than N minutes are qualified for trailing stop
    4. etc.
  • calculate a new stop-loss price for the position in question
    common methods :
    1. using Parabolic-SAR value of the previous bars
    2. using Moving Averages
    3. considering ATR indicator
    4. following current Bid( or Ask ) with a constant distance (e.g. 50 points)
    5. etc.
  • check the suggested stop-loss :
    1. distance between open price of position and the suggested SL, should be checked against stops level and/or freeze levels f symbol
    2. if Long position : suggested SL price should be higher than current SL of positions, but lower than current Bid.
    3. if Short position: suggested SL price should be lower than current SL of positions, but higher than current Ask.
  • set the calculated SL price to the position ( Position Modify part of code)
  • and then check the operation success and probably report the failures....
 

No but also 

-Start - when to start walking, it is only so logical when you want to start trailing from a specific point for example break even or > $0

-Stop - How much you want to walk behind, this can also be dynamic, like anti stop hunt, spread razor etc.

-Step - The size of the trailing steps, the distance between your feet when you walk.

 

look the original source and to understand how use it..

I put the peaces of code that you have use too..



original code:

https://www.mql5.com/pt/code/viewcode/19546/178536/ema_6.12.mq5


peace of code for trailing stop with step.





//---

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

CPositionInfo  m_position;                   // trade position object

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol;                     // symbol info object

//--- input parameters

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

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





double         ExtTrailingStop=0.0;

double         ExtTrailingStep=0.0;







-----in the OnInit----

(....)



   int digits_adjust=1;

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

      digits_adjust=10;

   m_adjusted_point=m_symbol.Point()*digits_adjust;



   ExtTakeProfit=InpTakeProfit*m_adjusted_point;

   ExtTrailingStop=InpTrailingStop*m_adjusted_point;

   ExtTrailingStep=InpTrailingStep*m_adjusted_point;

(....)





-----in the OnTick----



(....)

    Trailing();

(....)







-----------

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

//| Trailing                                                         |

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

void Trailing()

  {

   if(ExtTrailingStop==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());

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

                    }

              }



           }

  }





 
zemo:

look the original source and to understand how use it..

I put the peaces of code that you have use too..



original code:

https://www.mql5.com/pt/code/viewcode/19546/178536/ema_6.12.mq5


Great thank you very much, I will look into it!

Reason: