Coding Trailing Stop Loss in MQL5

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

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 if anyone would code it in my code or give me an MQL5 EA that already has a working trailing stop loss.

Thanks in advance,

Martin

 
Having the same problem with trying to code a two step stop loss that scans all open orders every tick and modifies them using these rules 

Rules:
start with static sl of 25 pips
at 5 pips profit move sl to entry price
at 8 pips profit move 4 pips behind 8 pips profit (current price)

Could somebody help? Thank you
 
Martin_2017: Could anyone please help me?
marth tanaka: Could somebody help?
Help you with what? You haven't stated a problem, you stated a want. Show us your attempt (using CODE button) and state the nature of your problem.
          No free help
          urgent help.
 
whroeder1:
Help you with what? You haven't stated a problem, you stated a want. Show us your attempt (using CODE button) and state the nature of your problem.
          No free help
          urgent help.

My bad--I just realized that I didnt. So here is my code so far,

//---- input parameters
extern double     InitialStop     = 25;
extern double     BreakEven       = 20;    // Profit Lock in pips  
extern double     StepSize        =  5;
extern double     MinDistance     = 10;

int   k, digit=0;
bool BE = false;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {

//----
   return(0);
  }

// ---- Stepped Stops
void StepStops()
{        
    double BuyStop, SellStop;
    int total=OrdersTotal();
    for (int cnt=0;cnt<total;cnt++)
    { 
     OrderSelect(cnt, SELECT_BY_POS);   
     int mode=OrderType();    
        if ( OrderSymbol()==Symbol() ) 
        {
            if ( mode==OP_BUY )
            {
               BuyStop = OrderStopLoss();
               if ( Bid-OrderOpenPrice()>0 || OrderStopLoss()==0) 
               {
               if ( Bid-OrderOpenPrice()>=Point*BreakEven && !BE) {BuyStop = OrderOpenPrice();BE = true;}
               
               if (OrderStopLoss()==0) {BuyStop = OrderOpenPrice() - InitialStop * Point; k=1; BE = false;}
               
               if ( Bid-OrderOpenPrice()>= k*StepSize*Point) 
               {
               BuyStop = OrderStopLoss()+ StepSize*Point; 
               if (Bid - BuyStop >= MinDistance*Point)
               { BuyStop = BuyStop; k=k+1;}
               else
               BuyStop = OrderStopLoss();
               }                              
               //Print( " k=",k ," del=", k*StepSize*Point, " BuyStop=", BuyStop," digit=", digit);
               OrderModify(OrderTicket(),OrderOpenPrice(),
                           NormalizeDouble(BuyStop, digit),
                           OrderTakeProfit(),0,LightGreen);
                              return(0);
                              }
                           }
            if ( mode==OP_SELL )
            {
               SellStop = OrderStopLoss();
               if ( OrderOpenPrice()-Ask>0 || OrderStopLoss()==0) 
               {
               if ( OrderOpenPrice()-Ask>=Point*BreakEven && !BE) {SellStop = OrderOpenPrice(); BE = true;}
               
               if ( OrderStopLoss()==0 ) { SellStop = OrderOpenPrice() + InitialStop * Point; k=1; BE = false;}
               
               if ( OrderOpenPrice()-Ask>=k*StepSize*Point) 
               {
               SellStop = OrderStopLoss() - StepSize*Point; 
               if (SellStop - Ask >= MinDistance*Point)
               { SellStop = SellStop; k=k+1;}
               else
               SellStop = OrderStopLoss();
               }
               //Print( " k=",k," del=", k*StepSize*Point, " SellStop=",SellStop," digit=", digit);
               OrderModify(OrderTicket(),OrderOpenPrice(),
                                  NormalizeDouble(SellStop, digit),
                                  OrderTakeProfit(),0,Yellow);      
               return(0);
               }    
            }
         }   
      } 
}

// ---- Scan Trades
int ScanTrades()
{   
   int total = OrdersTotal();
   int numords = 0;
      
   for(int cnt=0; cnt<total; cnt++) 
   {        
   OrderSelect(cnt, SELECT_BY_POS);            
   if(OrderSymbol() == Symbol() && OrderType()<=OP_SELL) 
   numords++;
   }
   return(numords);
}

                                    
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
   digit  = MarketInfo(Symbol(),MODE_DIGITS);

   
   if (ScanTrades()<1) return(0);
   else
   if (BreakEven>0 || InitialStop>0 || StepSize>0) StepStops(); 
   
 return(0);
}//int start
//+------------------------------------------------------------------+






I'm trying to modify this to make it do two steps. Using these following rules:


start with static sl of 25 pips
at 5 pips profit move sl to entry price
at 8 pips profit move 4 pips behind 8 pips profit (current price)


I already coded it in to start with a static stop loss of 25 pips. Now I'm just stuck on the last two parts. Thanks. OG code by igor