Question about iHighest Function

 

Hello to all MQL4 experts here,


Recently I've tried to code a trailing stop EA that trails behind the high of the highest bar from the current bar to the shift of the OrderOpenTime bar.

iHigh(_Symbol, _Period, (iHighest(_Symbol, _Period, MODE_HIGH, iBarShift(0, _Period, OrderOpenTime(), 0), 0)))

However, iBarShift is 0 shift at the OrderOpenTime bar which makes the iHighest function returning the barshift of the Highest High from the whole history before OrderOpenTime bar. Thus making the EA only work properly once OrderOpenTime barshift starts to become bigger than 1(When it no longer is the current bar).


How do you overcome this? Is there a way to make this work? Thanks

 
I-Kai Wu:

Hello to all MQL4 experts here,


Recently I've tried to code a trailing stop EA that trails behind the high of the highest bar from the current bar to the shift of the OrderOpenTime bar.

However, iBarShift is 0 shift at the OrderOpenTime bar which makes the iHighest function returning the barshift of the Highest High from the whole history before OrderOpenTime bar. Thus making the EA only work properly once OrderOpenTime barshift starts to become bigger than 1(When it no longer is the current bar).


How do you overcome this? Is there a way to make this work? Thanks

Please read the documentation https://www.mql5.com/en/docs/series/ibarshift

Documentation on MQL5: Timeseries and Indicators Access / iBarShift
Documentation on MQL5: Timeseries and Indicators Access / iBarShift
  • www.mql5.com
//| Script program start function                                    | //
 
I-Kai Wu: the high of the highest bar from the current bar to the shift of the OrderOpenTime bar.
  1. Don't write unreadable code.
    int     iOOT  = iBarShift(0, _Period, OrderOpenTime(), 0);
    int     iHH   = iHighest(_Symbol, _Period, MODE_HIGH, iOOT, 0);
    double   HH   = iHigh(_Symbol, _Period, iHH);
  2. Zero is not a symbol. Zero is not a bool.
  3. How many bars are there between OOT and bar zero (inclusive?) What are you passing?
 

Why do you start searching for the maximum from the time of opening an order? If OrderOpenTime is equal to the current time, you will only examine the current bar. Usually they look for the extreme value for the last N bars.


Here's the best trailing function for you:

//trailing market orders, the stop loss is kept at a Distance from the most extreme shadow of the last HoursNumber hours
int DoTrailOrders(double eDistance, double eHoursNumber, int eMagicNumber, string eSymbol, int eTimeFrame)
   {
   int eDigits=(int)MarketInfo(eSymbol,MODE_DIGITS);
   eDistance*=MarketInfo(eSymbol,MODE_POINT);
   double eSpread=MarketInfo(eSymbol,MODE_SPREAD)*MarketInfo(eSymbol,MODE_POINT);
   int eBarsNumber=(int)MathMax(MathCeil(3600.0/PeriodSeconds(eTimeFrame)*eHoursNumber),1);
   double eExtremum;
   int ePosition, eTotal=OrdersTotal(), eType;
   for(ePosition=0; ePosition<eTotal; ePosition++)
      {
      if(!OrderSelect(ePosition,SELECT_BY_POS,MODE_TRADES))
         {
         //error handling
         continue;
         }
      eType=OrderType();
      if(eType!=OP_BUY && eType!=OP_SELL) continue;
      if(OrderMagicNumber()!=eMagicNumber) continue;
      if(OrderSymbol()!=eSymbol) continue;
      //we observe starting from the bar following the opening bar
      if(iBarShift(eSymbol,eTimeFrame,OrderOpenTime())==0) continue;
      if(eType==OP_BUY)
         {
         //the stop is set at the distance eDistance from the lowest shadow of the bar in the history of eBarsNumber
         eExtremum=iLow(eSymbol,eTimeFrame,iLowest(eSymbol,eTimeFrame,MODE_LOW,eBarsNumber,1));
         //the distance from the minimum to StopLoss must exceed TrailingLevel
         if(NormalizeDouble(eExtremum-OrderStopLoss(),eDigits)<=eDistance && OrderStopLoss()>0) continue;
         //the distance from the minimum to the opening price must exceed TrailingLevel
         if(NormalizeDouble(eExtremum-OrderOpenPrice(),eDigits)<=eDistance) continue;
         //the new stop must be no closer to the current price than two spreads
         if(NormalizeDouble(MarketInfo(eSymbol,MODE_BID)-eExtremum+eDistance,eDigits)<=eSpread) continue;
         
         if(!OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(eExtremum-eDistance,eDigits),OrderTakeProfit(),OrderExpiration(),clOpenBuy))
            {
            //error handling
            }
         }
      if(eType==OP_SELL)
         {
         eExtremum=iHigh(eSymbol,eTimeFrame,iHighest(eSymbol,eTimeFrame,MODE_HIGH,eBarsNumber,1));
         if(NormalizeDouble(OrderStopLoss()-eExtremum,eDigits)<=eDistance && OrderStopLoss()>0) continue;
         if(NormalizeDouble(OrderOpenPrice()-eExtremum,eDigits)<=eDistance) continue;
         if(NormalizeDouble(eExtremum+eDistance-MarketInfo(eSymbol,MODE_ASK),eDigits)<=eSpread) continue;
         if(!OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(eExtremum+eDistance,eDigits),OrderTakeProfit(),OrderExpiration(),clOpenSell))
            {
            //error handling
            }
         }
      }
   return(0);
   }
Reason: