Coding Trailing Stop Loss in MQL5

To add comments, please log in or register
Martin
95
Martin  

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...
amando
1656
amando  

there is the position modfy function missing

Tafadzwa Nyamwanza
387
Tafadzwa Nyamwanza  
Try the wizard 
Martin
95
Martin  
amando:

there is the position modfy function missing

Where?

Tafadzwa Nyamwanza:
Try the wizard 

What's that?

Code2219 or 2319
494
Code2219 or 2319  
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....
Marco vd Heijden
Moderator
11593
Marco vd Heijden  

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.

zemo
418
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


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

                    }

              }



           }

  }





Martin
95
Martin  
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!

To add comments, please log in or register