Data is outdated when requested

 

Hi everybody.

I have a pipe connection with my app and Mt4. 

Working very very well for years.

But since the beginning I have the same problem: When I request new data from a pair, I will receive an outdated data.

For example: If I open EURUSD in first time in the day, the last data will the same when I closed in last time and more one candle with the new current price...Crazy...See the image attached:

mt4

Solution: I request again, so now the data will be update and everything will work fine.

      Buffer_Old = TimeToStr(iTime(pair, timeFrame, bars_count), TIME_DATE) + "," + TimeToStr(iTime(pair, timeFrame, bars_count), TIME_MINUTES) + "," + DoubleToStr(iOpen(pair, timeFrame, bars_count),  MarketInfo(pair,MODE_DIGITS)) + "," + DoubleToStr(iClose(pair, timeFrame, bars_count),  MarketInfo(pair,MODE_DIGITS)) + "," + DoubleToStr(iHigh(pair, timeFrame, bars_count),  MarketInfo(pair,MODE_DIGITS)) + "," + DoubleToStr(iLow(pair, timeFrame, bars_count),  MarketInfo(pair,MODE_DIGITS));

I am using the code above to get the data. This code is inside a loop to get 200 bars. 

I tried to put in everywhere RefreshRate()...And remove too...Feed a variable in the beginning to maybe force the mt4 download data...Using a While until RefreshRate return true...But nothing works...

As you can see, I request for Symbols that aren't in chart. I only use a EURUSD chart to put my script...But I download more then 32 pairs...

void TestIfUpdated(string pair, ENUM_TIMEFRAMES period){
       while(true){          
          datetime a1 = TimeMinute(TimeLocal());
          datetime a2 = TimeMinute(iTime(pair, period,0));         
          if(a1 != a2){
              //Print("outdated");
              RefreshRates();
              //here I think that I need to do something to force this data updating.. 
          }else{
              //Print("updated");
              break;
          }
       }
  }

In the above part of my script, I tried to create this Tester...Work fine, but only to know if data is outdated or not...But what Can I do to force an updating? The curious is that this script after RefreshRates will exit saing that the data is Updated but is not true, I keeping receiving outdated data.

Thanks for your help!

EURUSD - Euro vs US Dollar - Today's currency exchange rates — Forex exchange rates
EURUSD - Euro vs US Dollar - Today's currency exchange rates — Forex exchange rates
  • www.mql5.com
EURUSD - Euro vs US Dollar - Most popular currency pair charts. Use the filter below to select the exchange rates you need. Each chart features Bid/Ask prices, as well as daily growth.
 

I forget to say that I use this code in a Script.

My app send a command via pipe and this script execute some function that in the case is just save a .csv file

for(int k = (200 - 1); k >= 0; k--)  
  {
     Buffer_New = TimeToStr(iTime(pair, period, k), TIME_DATE);
  } 

I tried this code above try forcing a download. Not worked. So I put a big Sleep after this just to give a time for mt4 write in buffer the data and.....not worked...

I find this thread: https://www.mql5.com/en/forum/143422

For me doesnt worked...But have a good info...

Problems with ERR_HISTORY_WILL_UPDATED (4066 ) & weekends
Problems with ERR_HISTORY_WILL_UPDATED (4066 ) & weekends
  • 2013.02.09
  • www.mql5.com
Hi i m building a custom indicator and got problems with the 4066 Error...
 

https://www.mql5.com/en/forum/160686

here we have a lot information about this problem...

lets go...

how to refresh symbol data
how to refresh symbol data
  • 2016.11.09
  • www.mql5.com
Hi, I have a script to scan candlestick pattern on multiple symbols...
 


//This for is called 32 times with differents pairs
for
(int in = 0; in < 6; in++) //Six because I am saving 6 timeFrames in 6 files csv...      {       periodo    = StrToInteger(StringSpliter(Pairs_Time_Infos[in], "@", 1)); //can be 1,5,15,60,1440,10080.       bars_count = StrToInteger(StringSpliter(Pairs_Time_Infos[in], "@", 3)); //200,200,3461,3461,1000,587.       FullName   = pathName + StringSpliter(Pairs_Time_Infos[in], "@", 2);    //One.csv,Five.csv,Fiftteen.csv...       ResetLastError();       Buffer_Old = TimeToStr(iTime(paridade, periodo, bars_count), TIME_DATE) + "," + TimeToStr(iTime(paridade, periodo, bars_count), TIME_MINUTES) + "," + DoubleToStr(iOpen(paridade, periodo, bars_count), 5) + "," + DoubleToStr(iClose(paridade, periodo, bars_count), 5) + "," + DoubleToStr(iHigh(paridade, periodo, bars_count), 5) + "," + DoubleToStr(iLow(paridade, periodo, bars_count), 5);            for(int k = (bars_count - 1); k >= 0; k--)         {          Buffer_New = TimeToStr(iTime(paridade, periodo, k), TIME_DATE) + "," + TimeToStr(iTime(paridade, periodo, k), TIME_MINUTES) + "," + DoubleToStr(iOpen(paridade, periodo, k), 5) + "," + DoubleToStr(iClose(paridade, periodo, k), 5) + "," + DoubleToStr(iHigh(paridade, periodo, k), 5) + "," + DoubleToStr(iLow(paridade, periodo, k), 5);                 Buffer_Old = Buffer_Old + "\r\n" + Buffer_New;       }       fWrite = CreateFileW(FullName, GENERIC_WRITE, ShareMode, 0, CREATE_ALWAYS, 0, 0);       if(fWrite == INVALID_HANDLE_VALUE)         {         }       else         {          szData = StringLen(Buffer_Old);          WriteFile(fWrite, Buffer_Old, 2 * szData, BytesWritten, NULL);          CloseHandle(fWrite);         }      }
Here the entire code...I tried many things...Put a Sleep() between each time I call Buffer_Old...Sometimes I receive the error 4051 because the result is 1970.01.01....Sometimes I receive the error 4066...I tried to recall when 4066 but same problem...
 
Buffer_Old = TimeToString(iTime(paridade, periodo, bars_count), TIME_DATE) + "," + TimeToString(iTime(paridade, periodo, bars_count), TIME_MINUTES) + "," + DoubleToString(iOpen(paridade, periodo, bars_count), 5) + "," + DoubleToString(iClose(paridade, periodo, bars_count), 5) + "," + DoubleToString(iHigh(paridade, periodo, bars_count), 5) + "," + DoubleToString(iLow(paridade, periodo, bars_count), 5);
      if(_LastError != 0){
          Print("a= " + paridade + "periodo= " + periodo + "k= " + bars_count + " " + _LastError);
          ResetLastError();
          Sleep(10);
          Buffer_Old = TimeToString(iTime(paridade, periodo, bars_count), TIME_DATE) + "," + TimeToString(iTime(paridade, periodo, bars_count), TIME_MINUTES) + "," + DoubleToString(iOpen(paridade, periodo, bars_count), 5) + "," + DoubleToString(iClose(paridade, periodo, bars_count), 5) + "," + DoubleToString(iHigh(paridade, periodo, bars_count), 5) + "," + DoubleToString(iLow(paridade, periodo, bars_count), 5);
      }
      if(_LastError != 0){
          Print("b= " + paridade + "periodo= " + periodo + "k= " + bars_count + " " + _LastError);
          ResetLastError();
      }

Doing this code I solved the error 4066...

Now I need just solve the error 4051...This error only appear in second test of errors in Print(b=... This 4051 says  ERR_INVALID_FUNCTION_PARAMVALUE but the parameters are correct, works in all. 

2021.08.26 08:16:20.879 ReceiveCommandsFromIST NAS100.a,H1: a= EURJPYperiodo= 1440k= 1000 4066
2021.08.26 08:16:20.803 ReceiveCommandsFromIST NAS100.a,H1: b= EURJPYperiodo= 240k= 3461 4051
2021.08.26 08:16:20.790 ReceiveCommandsFromIST NAS100.a,H1: a= EURJPYperiodo= 240k= 3461 4066
2021.08.26 08:16:20.740 ReceiveCommandsFromIST NAS100.a,H1: b= EURJPYperiodo= 60k= 3461 4051
2021.08.26 08:16:20.727 ReceiveCommandsFromIST NAS100.a,H1: a= EURJPYperiodo= 60k= 3461 4066
2021.08.26 08:16:20.676 ReceiveCommandsFromIST NAS100.a,H1: b= EURJPYperiodo= 15k= 3461 4051
2021.08.26 08:16:20.653 ReceiveCommandsFromIST NAS100.a,H1: a= EURJPYperiodo= 15k= 3461 4066
2021.08.26 08:16:20.620 ReceiveCommandsFromIST NAS100.a,H1: a= EURJPYperiodo= 5k= 200 4066
2021.08.26 08:16:20.593 ReceiveCommandsFromIST NAS100.a,H1: a= EURJPYperiodo= 1k= 200 4066
2021.08.26 08:16:20.565 ReceiveCommandsFromIST NAS100.a,H1: a= EURUSDperiodo= 1440k= 1000 4066
2021.08.26 08:16:20.503 ReceiveCommandsFromIST NAS100.a,H1: a= EURUSDperiodo= 240k= 3461 4066
2021.08.26 08:16:20.442 ReceiveCommandsFromIST NAS100.a,H1: a= EURUSDperiodo= 60k= 3461 4066
2021.08.26 08:16:20.370 ReceiveCommandsFromIST NAS100.a,H1: a= EURUSDperiodo= 15k= 3461 4066
2021.08.26 08:16:20.337 ReceiveCommandsFromIST NAS100.a,H1: a= EURUSDperiodo= 5k= 200 4066
2021.08.26 08:16:20.310 ReceiveCommandsFromIST NAS100.a,H1: a= EURUSDperiodo= 1k= 200 4066


Probably is something with History because if I change this number 3461 that are my last candle in my csv to for example 2000 I didnt receive this error 4051...

EDIT1: Ok, I used IBars to know how many bars I have for selected symbol and voila, I have only 2108 bars for 4h timeframe...

 

On MT4: Unless the current chart is that specific symbol(s)/TF(s) referenced, you must handle 4066/4073 errors before accessing candle/indicator values.
          Download history in MQL4 EA - Forex Calendar - MQL4 programming forum - Page 3 #26.4 (2019.05.20)

On MT5: Unless the current chart is that specific pair/TF, you must synchronize the terminal Data from the Server before accessing candle/indicator values.
          Error 4806 while using CopyBuffer() - Expert Advisors and Automated Trading - MQL5 programming forum #10 (2020.12.15)
          Is it mystical?! It is! - Withdraw - Technical Indicators - MQL5 programming forum (2019.05.31)
          Timeseries and Indicators Access / Data Access - Reference on algorithmic/automated trading language for MetaTrader 5
          Synchronize Server Data with Terminal Data - Symbols - General - MQL5 programming forum #2 (2018.07.17)
          SymbolInfoInteger doesn't work - Symbols - General - MQL5 programming forum (2019.09.03)

 
for(int in = 0; in < 6; in++) 
     {
      periodo    = StrToInteger(StringSpliter(Pairs_Time_Infos[in], "@", 1)); // 1,5,15,60,1440,10080.
      bars_count = StrToInteger(StringSpliter(Pairs_Time_Infos[in], "@", 3)); //200,200,3461,3461,1000,587.
      if(iBars(paridade, periodo) < bars_count){
          bars_count = iBars(paridade, periodo)-1;
      }
      FullName   = pathName + StringSpliter(Pairs_Time_Infos[in], "@", 2);    //Um.csv,Cinco.csv,Quinze.csv...
      ResetLastError();
      Buffer_Old = TimeToString(iTime(paridade, periodo, bars_count), TIME_DATE) + "," + TimeToString(iTime(paridade, periodo, bars_count), TIME_MINUTES) + "," + DoubleToString(iOpen(paridade, periodo, bars_count), 5) + "," + DoubleToString(iClose(paridade, periodo, bars_count), 5) + "," + DoubleToString(iHigh(paridade, periodo, bars_count), 5) + "," + DoubleToString(iLow(paridade, periodo, bars_count), 5);
      if(_LastError != 0){
          //Print("a= " + paridade + "periodo= " + periodo + "k= " + bars_count + " " + _LastError);
          ResetLastError();
          Sleep(1);
          Buffer_Old = TimeToString(iTime(paridade, periodo, bars_count), TIME_DATE) + "," + TimeToString(iTime(paridade, periodo, bars_count), TIME_MINUTES) + "," + DoubleToString(iOpen(paridade, periodo, bars_count), 5) + "," + DoubleToString(iClose(paridade, periodo, bars_count), 5) + "," + DoubleToString(iHigh(paridade, periodo, bars_count), 5) + "," + DoubleToString(iLow(paridade, periodo, bars_count), 5);
      }
      if(_LastError != 0){
          //Print("b= " + paridade + "periodo= " + periodo + "k= " + bars_count + " " + _LastError);
          ResetLastError();
          //Print(TimeToString(iTime(paridade, periodo, bars_count-1), TIME_DATE) + "," + TimeToString(iTime(paridade, periodo, bars_count-1), TIME_MINUTES) + "," + DoubleToString(iOpen(paridade, periodo, bars_count-1), 5) + "," + DoubleToString(iClose(paridade, periodo, bars_count-1), 5) + "," + DoubleToString(iHigh(paridade, periodo, bars_count-1), 5) + "," + DoubleToString(iLow(paridade, periodo, bars_count-1), 5));
          //Print(iBars(paridade, periodo)); 
      }
      for(int k = (bars_count - 1); k >= 0; k--) 
      {
         Buffer_New = TimeToString(iTime(paridade, periodo, k), TIME_DATE) + "," + TimeToString(iTime(paridade, periodo, k), TIME_MINUTES) + "," + DoubleToString(iOpen(paridade, periodo, k), 5) + "," + DoubleToString(iClose(paridade, periodo, k), 5) + "," + DoubleToString(iHigh(paridade, periodo, k), 5) + "," + DoubleToString(iLow(paridade, periodo, k), 5);
         Buffer_Old = Buffer_Old + "\r\n" + Buffer_New;
      } //Fecha for(int k=0;k<=bars_count;k++)
      msgBox(modeDebug,"will create a csv file");
      fWrite = CreateFileW(FullName, GENERIC_WRITE, ShareMode, 0, CREATE_ALWAYS, 0, 0);
      if(fWrite == INVALID_HANDLE_VALUE)
        {
         msgBox(modeDebug,"Unable to open " + FullName + " for writing");
        }
      else
        {
        
         szData = StringLen(Buffer_Old);
         WriteFile(fWrite, Buffer_Old, 2 * szData, BytesWritten, NULL);
         CloseHandle(fWrite);
        } //Fecha o Else do if (!IsValidFileHandle(fWrite))
     }//for (int in = 0; in

ok, above the code working fine. I solved puting this lines in code:

      bars_count = StrToInteger(StringSpliter(Pairs_Time_Infos[in], "@", 3)); //200,200,3461,3461,1000,587.
      if(iBars(paridade, periodo) < bars_count){
          bars_count = iBars(paridade, periodo)-1;
      }

Unfortunately, I have only 2108 bars in 4H in my history. I  try to download more but dont exist more to donwload...

So now solved all erros...


Thanks all

 

Good links to reference:

Errors codes: https://docs.mql4.com/constants/errorswarnings/errorcodes

Problems with ERR_HISTORY_WILL_UPDATED (4066 ) & weekends: https://www.mql5.com/en/forum/143422

Some description about error 4066: https://docs.mql4.com/array/arraycopyseries and here https://docs.mql4.com/series

Download history in MQL4 EA: https://www.mql5.com/en/forum/188001/page1

Runtime Errors - Codes of Errors and Warnings - Constants, Enumerations and Structures - MQL4 Reference
Runtime Errors - Codes of Errors and Warnings - Constants, Enumerations and Structures - MQL4 Reference
  • docs.mql4.com
Runtime Errors - Codes of Errors and Warnings - Constants, Enumerations and Structures - MQL4 Reference
 

Unfortunately here a very bed information:

When referring the to MQL4, the implementation of this error is a dummy. First call to a particular function sets error 4066, while any subsequent resets it. This error is not related to the actual status of data update in the MT4 terminal.

Indicators can not wait. They must return immediately.

The first time you will get 4066. On subsequent calls dt will still be zero but GLE will NOT be 4066. Just return.


I took this citation from an another post...So if I understand, the point is that is impossible to deal definitely with this issue.

Because I still with the same initial problem. In the first call my csv files are outdated...In second call ok. 

When I receive this erros 4066 I used A Sleep(5000); to wait the "download" and the same problem. I received just one error, no more, but the quotes in csv are outdated...


Whats I dont understand is WHY Metatrader doesnt make a simple little line code to solve this so old problem...Just something like While(isUpdating()){...}  To implement this in the source code is really so hard? And I saw that is a recurrent problem in mql5 too!!

 

Unfortunately I give up. I decided to use another approach. As I have my personal app, I  did in less than 10 lines a verification. If chart is outdated I simple call again an Update and voilá...Less than 1 second and chart is totaly updated...I cant  understanding why mt4 dont implement this but ok, they are focusing in mt5 and I think that things like this is a way to force us to migrate to mt5. And ok, I will. I already did, but I receive an fatal strange error in my pipeline in mt5 so for now I dont have time...

Thanks.