Why is Metatrader always one candle behind?

 

So, take the following code.

Load it up on a chart of your choosing (except AUDJPY), any pair any time frame (I'd recommend 15min or greater).  Let it run so you at least get a few candles in.  Make sure whatever timeframe you choose, you don't have .hst file for AUDJPY in that timeframe.  ie., AUDJPY15.hst for 15 min.

Once done, remove the EA.  Open the AUDJPY chart on the timeframe.  Open the CSV it creates.  You'll see the first value is 0.  Then all values there after are "one candle behind".

Can anyone explain this, or know of a fix for it?

Date/Time Other Pair
2014.11.19 16:45:00 0
2014.11.19 17:00:00 101.473
2014.11.19 17:15:00 101.531
2014.11.19 17:30:00 101.523

All the prices should be up one and the 0 not in the table.

//+------------------------------------------------------------------+
//|                                                     Log test.mq4 |
//|                                    Copyright 2014, Nondisclosure |
//|                                               http://no.link.yet |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Nondisclosure"
#property link      "http://no.link.yet"
#property version   "1.00"
#property strict


string filename="Log test.csv";
int handle;
datetime LastTime;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   string header="Date/Time,Other Pair";
   LastTime=Time[0];
   handle=FileOpen(filename,FILE_WRITE|FILE_CSV);
   FileWrite(handle,header);
   Comment(" ");
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   string LineData;
   bool NewBar=funcIsNewBar();
   if(NewBar)
   {
     LineData=StringConcatenate(Time[1],",",iClose("AUDJPY",0,1));
     FileWrite(handle,LineData);      
   }
}

bool funcIsNewBar()
{
   bool ReturnValue=false;
   if(LastTime != Time[0]) 
   {
      ReturnValue=true;
      LastTime=Time[0];   
   }
   return(ReturnValue);
}
 
nondisclosure: You'll see the first value is 0.  Then all values there after are "one candle behind". Can anyone explain this, or know of a fix for it?
iClose("AUDJPY",0,1)
  1. The first zero is because you got

    4066

    ERR_HISTORY_WILL_UPDATED

    Requested history data is in updating state

    and you didn't handle it
  2. Your new bar code triggers on the current pair. There is no guarantee that when the current pair ticks, that the "other" pair already has.
  3. You assume that bar index 1 on the current chart is the same bar index 1 on the other pair. Don't assume, use iBarShift("AUDJPY",0, Time[1])
 
WHRoeder:
  1. The first zero is because you got

    4066

    ERR_HISTORY_WILL_UPDATED

    Requested history data is in updating state

    and you didn't handle it
  2. Your new bar code triggers on the current pair. There is no guarantee that when the current pair ticks, that the "other" pair already has.
  3. You assume that bar index 1 on the current chart is the same bar index 1 on the other pair. Don't assume, use iBarShift("AUDJPY",0, Time[1])

Thanks WHRoeder.

1.  Good hit my friend!!  I can see how that can happen on the first one, but I don't understand how ArrayCopySeries is a way to handle it.  Can you explain?

2. Shouldn't all pairs tick at the same time for a new bar?

3. I tried iBarShift and got the same results on the first bar.  When there wasn't an updated history, I got the last value.

So I guess my question is this, how can I assure I get the correct value?

 
nondisclosure:

1.  Good hit my friend!!  I can see how that can happen on the first one, but I don't understand how ArrayCopySeries is a way to handle it.  Can you explain?

2. Shouldn't all pairs tick at the same time for a new bar?

3. I tried iBarShift and got the same results on the first bar.  When there wasn't an updated history, I got the last value.

So I guess my question is this, how can I assure I get the correct value?

  1. ACS isn't the way to handle it. Look at the example, how it checks, sleeps, and retries.
  2. A pair ticks when someone in the worlds does a buy or sell. If that is after the bar start + period in seconds a new bar forms. No trade, no new bar. "Free-of-Holes" Charts - MQL4 Articles
  3. No tick, no change.
  4. You are getting the correct values. Change new bar to look at the pair, not the chart. You still have to handle the fact that OnTick may not be called but multiple bars formed on the other chart. Alternatively, just handle the current pair and put your code on multiple charts.


 

WHRoeder:

No trade, no new bar.

[ Bid and offer can change without a trade occurring and, conversely, there can be trades without the bid and offer changing. A tick in MT4 is a change in the top-of-book price (or a few other criteria), not necessarily a trade. ]