EA MT4: Finding the high and low between now and a previous trade datetime

 

Hi all

I've been racking my brain on this all afternoon and can't work out where I'm going wrong... 

My goal is to find the high/low between now and a previous trade.

I know the general gist of it is 

(1) find current datetime and past reference datetime

(2) find the hours between the two datetimes (Im using H1 period)

(3) Work out how many periods ago the past reference datetime is using iBarShift

(4) Find the high/low using iHighest/iLowest

(5) Use high/low to return the highest/lowest value

Below is some code I've found in forums that I figure should work but I keep getting the same issue... it returns the highest/lowest value for periods much further in the past than is correct.

//Example 1

datetime fromDT = dt_TradeTime,
           toDT = TimeCurrent();
int      fromBar = iBarShift(NULL, 0, fromDT),
           toBar = iBarShift(NULL, 0,   toDT),
          length = fromBar - toBar + 1,
           LLbar =  iLowest(NULL,0, MODE_LOW,  length, toBar);
double     LL    =  Low[LLbar];

Any help would be much appreciated!

 
alex532110:

Hi all

Any help would be much appreciated!

You just use bellow code where dt_TradeTime is time of previous trade.

double LL=Low[iLowest(_Symbol,_Period,MODE_LOW,iBarShift(_Symbol,_Period,dt_TradeTime)+1)];
 
Petr Nosek:

You just use bellow code where dt_TradeTime is time of previous trade.

Hi Petr. Thank you for your reply.


I still get the same issue with your code. Somehow the number iBarShift returns is an ever increasing number of bars throughout the backtest.

   // Initial Buy conditions
   if(l_TotalTrades_buy == 0 && trade_indicator1 < CLOSE && stop_indictator1 < CLOSE) 
   {
      CloseOrder(OP_SELL);
      PlaceOrder(OP_BUY, GetLotSize(OP_BUY));
      dt_TradeTime_B1 = TimeCurrent();
   }  

   // Buy on retracements 1


double HH_B1 =High[iHighest(_Symbol,_Period,MODE_HIGH,iBarShift(_Symbol,_Period,dt_TradeTime_B1),0)];


     if(l_TotalTrades_buy == 1 && trade_indicator1 < CLOSE && stop_indicator2 < CLOSE && Ask < .98*HH_B1) 
   {
      Alert("High: " + HH_B1 + " .... Number of Bars: " + iBarShift(_Symbol,_Period,dt_TradeTime_B1));
      PlaceOrder(OP_BUY, GetLotSize(OP_BUY));
   }  

 It may have something to do with the TradeTime not resetting with each initial Buy trade... but i don't see why it wouldn't.

 
alex532110:

Hi Petr. Thank you for your reply.


I still get the same issue with your code. Somehow the number iBarShift returns is an ever increasing number of bars throughout the backtest.

 It may have something to do with the TradeTime not resetting with each initial Buy trade... but i don't see why it wouldn't.

It must have to do with the dt_TradeTime. You have to check your code and look for logic error in setting the dt_TradeTime. Add this piece of code to check the dt_TradeTime

printf("Trade time: %s",TimeToStr(dt_TradeTime));

or

Alert("Trade time: "+TimeToStr(dt_TradeTime));

P.S.

I've updated my previous post. If you want to compare dt_TradeTime bar too you have to increase the length. But this doesn't have to do with your problem.

double LL=Low[iLowest(_Symbol,_Period,MODE_LOW,iBarShift(_Symbol,_Period,dt_TradeTime)+1)];
 

alex532110: (2) find the hours between the two datetimes (Im using H1 period)

  1. No!. No ticks during a period, no bars during the period. This assumes every bar every exists. What if there are no ticks during a specific candle period? There can be minutes between ticks during the Asian session, think M1 chart. Larger charts, think weekends and market holidays.
              "Free-of-Holes" Charts - MQL4 Articles
              No candle if open = close ? - MQL4 and MetaTrader 4 - MQL4 programming forum

  2. Code it just like you said. Write self-documenting code.
    // (1) find current datetime and past reference datetime
    datetime current  = ...;
    datetime previous = ...;
    
    // (2) find the hours between the two datetimes (Im using H1 period)
    // No and unnecessary.
    
    //(3) Work out how many periods ago the past reference datetime is using iBarShift
    int iCurrent  = iBarShift(_Symbol, _Period, current);
    int iPrevious = iBarShift(_Symbol, _Period, previous);
    
    // (4) Find the high/low using iHighest/iLowest
    int nBars = iPrevious - iCurrent + 1;
    int iHH   = iHighest(_Symbol, _Period, MODE_HIGH, nBars, iCurrent);
    int iLL   =  iLowest(_Symbol, _Period, MODE_LOW,  nBars, iCurrent);
    
    // (5) Use high/low to return the highest/lowest value
    double HH = High[iHH];
    double LL =  Low[iLL];

 
whroeder1:
  1. No!. No ticks during a period, no bars during the period. This assumes every bar every exists. What if there are no ticks during a specific candle period? There can be minutes between ticks during the Asian session, think M1 chart. Larger charts, think weekends and market holidays.
              "Free-of-Holes" Charts - MQL4 Articles
              No candle if open = close ? - MQL4 and MetaTrader 4 - MQL4 programming forum

  2. Code it just like you said. Write self-documenting code.

Your code will have the same result as my code. But it is written on many more lines. I do not prefer such a waste, but for someone, your code can be better understood.

As @alex532110 said: "My goal is to find the high/low between now and a previous trade." In this case your iCurrent is always equal to zero and your nBars is always equal to iPrevious+1.

But mainly, it does not solve his problem. His problem is in setting "dt_TradeTime".
 
Petr Nosek: But it is written on many more lines. I do not prefer such a waste, but for someone, your code can be better understood.
  1. When you have to come back to some code months later and have to re-understand what it's doing, you will understand such "waste."
  2. If current is always now, don't remove it, don't state that nBars = prev-1. Write self-documenting code:
    // int iCurrent  = iBarShift(_Symbol, _Period, current);
    const int iCurrent = 0;
    int nBars = iPrevious - iCurrent + 1;

 
whroeder1:
  1. When you have to come back to some code months later and have to re-understand what it's doing, you will understand such "waste."


Yes. A little effort now can save a lot of effort later.

 
Anthony Garot:


Yes. A little effort now can save a lot of effort later.

In that case why not also use MQL5 compatible code instead of relying on deprecated MQL4 features? 


   datetime from_time; //last trade time
   double highs[],lows[];
   int total_high = CopyHigh(_Symbol,_Period,from_time,TimeCurrent(),highs);
   int total_low  = CopyLow (_Symbol,_Period,from_time,TimeCurrent(),lows);
   if(total_high != total_low)
      Print("ERROR = ",_LastError);
   printf("The high since the last order is %f and the low since the last order is %f",
          highs[ArrayMaximum(high)],
          lows[ArrayMinimum(lows)]);
 
whroeder1:
  1. When you have to come back to some code months later and have to re-understand what it's doing, you will understand such "waste."

Be sure sometimes I have to come back to some my code months or years later and if my code contains more than 10 000 lines I'm usually glad that it doesn't contain such waste. And I'm not talking about code efficiency.

If I need to I can add a remark like this: 

// Lowest price from now to the previous trade time
double LL=Low[iLowest(_Symbol,_Period,MODE_LOW,iBarShift(_Symbol,_Period,dt_TradeTime)+1)];
 
SanjayBalraj:

In that case why not also use MQL5 compatible code instead of relying on deprecated MQL4 features? 

Because the broker may not have the MT5 platform.