EA trail stop based on movement from opening price

 

I have an EA I am working on but I can't get the trailing stop to work. The original stop loss is at the low/high of the candle we will call it Xrange and as price moves away from open I want to trail it by values of X
the rules I am looking to implement are:
when price moves away from the open price 50% of the distance of the opening price and the SL the SL moves to BE
when price moves away from opening price moves 2 Xranges the original SL distance it moves in profit to 1 Xrange
the stop loss continues to follow price up

the code is MQL5

void OnTick(){

   int bars = iBars(_Symbol,PERIOD_CURRENT);
   if(bars > totalBars){
   totalBars = bars;
   double lots;
   int engulfingSignal = getEngulfingSignal();
   if(engulfingSignal < 0){
   Print(__FUNCTION__,"Bearish Buy Signal");
   slDistance = iOpen(_Symbol,PERIOD_CURRENT,1) - iClose(_Symbol,PERIOD_CURRENT,1);
   calcLots();
   lots = calcLots();
   trade.BuyStop(lots,iOpen(_Symbol,PERIOD_CURRENT,1),_Symbol,iClose(_Symbol,PERIOD_CURRENT,1),0,ORDER_TIME_GTC,0,"Engulfing");
   }else if(engulfingSignal > 0){
   Print(__FUNCTION__,"Bullish Sell Signal");
   slDistance = iClose(_Symbol,PERIOD_CURRENT,1) - iOpen(_Symbol,PERIOD_CURRENT,1);
   calcLots();
   lots = calcLots();
   trade.SellStop(lots,iOpen(_Symbol,PERIOD_CURRENT,1),_Symbol,iClose(_Symbol,PERIOD_CURRENT,1),0,ORDER_TIME_GTC,0,"Engulfing");
   }
   }
   
  for(int i = PositionsTotal()-1; i >= 0; i--){
  ulong posTicket = PositionGetTicket(i);
  
   if(PositionSelectByTicket(posTicket)){
      if(PositionGetString(POSITION_SYMBOL)==_Symbol){
      double beSL;
      int n;
      double newSL; 
      double bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
      if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
            n =1;
            beSL = PositionGetDouble(POSITION_PRICE_OPEN);
            newSL = (((PositionGetDouble(POSITION_PRICE_OPEN) - PositionGetDouble(POSITION_SL)) * n));
            if(bid > (beSL + newSL)){
         
               if(trade.PositionModify(posTicket,beSL,0)){
                     Print(__FUNCTION__, "Position was modified");
      }
      }
      
      }
   }
  
  }
}
}

Here is a picture of what I am looking to achieve. 


I appreciate any help

 

Hi

Your code for first movement is correct – but it will be working only for this first step – since you won't be able to get initial distance this way. You need to ether save this calculated range for each position as a global variable to have access later for it (which requires some special management). Or calculate the range each time when you modify the trades – based on the open time and prices on the candle then: read open time of the trade, get number of candle on which trade was opened, then get the low/high price of this candle and then you would have the range which can be used for trailing calculations. And then you can calculate the multiplier this way for buy:

range;       

beSL = PositionGetDouble(POSITION_PRICE_OPEN);

if(bid>(beSL+range/2)){

        int n = MathFloor((bid-beSL)/range);      //how many times higher

        if(n<1)

               newSL = beSL; //set on BE

        else newSL  = beSL-range*(n-1); //set on range dstance

}

Of course here there should be some normalization of prices, checking the stoplevel/freezelevel or even checking if new SL is higher than current sl etc. But the idea may be coded this way.

Best Regards