History file reading problem

erzo
109
Hello,
I want to use History file to manipulate candle data, write it to a History file, and after that use in technical indicators, from script/ea. The History file writing is Ok, but the system does not want to read and synchronize data automatically from it if I call an indicator from the code. Maybe there is a command to refresh indicators? Or what I'm doing wrong?..
If you have other solution to use array data in iCustom input, also it woud be great.
This is my mq4 test script:
#include <WinUser32.mqh>
#include <stdlib.mqh>

string SymbolName = "EURUSD";

int start() {
   // create / open hst file            
   int historyFileHandle = FileOpenHistory(SymbolName + "3.hst", FILE_BIN|FILE_WRITE);
   if(historyFileHandle < 0) {
      Print("Error: can\'t create / open history file: " + ErrorDescription(GetLastError()) + ": " + SymbolName + "3.hst");
      return(-1);
   }
   
   // write hst file header
   int historyUnused[13];
   FileWriteInteger(historyFileHandle, 400, LONG_VALUE); // Version
   FileWriteString(historyFileHandle, "", 64); // Copyright
   FileWriteString(historyFileHandle, SymbolName, 12); // Symbol
   FileWriteInteger(historyFileHandle, 3, LONG_VALUE); // Period
   FileWriteInteger(historyFileHandle, Digits, LONG_VALUE); // Digits
   FileWriteInteger(historyFileHandle, 0, LONG_VALUE); // Time Sign
   FileWriteInteger(historyFileHandle, 0, LONG_VALUE); // Last Sync
   FileWriteArray(historyFileHandle, historyUnused, 0, 13); // Unused

   // process historical data
   int i;
   for (i = Bars - 1; i >= 0; i--) {
      FileWriteInteger(historyFileHandle, Time[i], LONG_VALUE);
      FileWriteDouble(historyFileHandle, Open[i] + 20 * Point, DOUBLE_VALUE);
      FileWriteDouble(historyFileHandle, Low[i] + 20 * Point, DOUBLE_VALUE);
      FileWriteDouble(historyFileHandle, High[i] + 20 * Point, DOUBLE_VALUE);
      FileWriteDouble(historyFileHandle, Close[i] + 20 * Point, DOUBLE_VALUE);
      FileWriteDouble(historyFileHandle, Volume[i], DOUBLE_VALUE);
   }

   // close file
   if(historyFileHandle >= 0) {
      FileClose(historyFileHandle);
   }

   // print last (original) close: it works.
   Print(iClose("EURUSD", 1, 0));
   
   // !!!!!!!!!!!!!!!!! Why not works this immediately?
   Print(iClose("EURUSD", 3, 0));
   // After manually open the history file and run this script again on EURUSD M1, writes the data,
   // but does not refresh: writes always the same, until manually refreshing in the other (the opened history!) chart
   
   return(0);
}
erzo
109
erzo  
Nobody uses Renko/Tlb/Pf charting in EA? Or who uses, re-develops all the indicators into OnArray-like to run it on array data? We always write iCustom(Null, 0 ..., but now I wanted to use that two parameters, but it seems simply not working at irregular timeframes. And it is buggy at regular timeframes too, if that timeframe was not opened in any window so far, and MT has no history file for it. Try the following script. (By the way, MT5 removes even the history file accessibility.)
// Terminal and editor version: 4.00 build 419
// To reproduce bug, do following:
// - after compiling this script, stop Terminal and Editor
// - delete all NZDUSD history file if there is any
// - start Terminal
// - open a chart: NZDUSD H1 (H1 is default if open from toolbar)
// - place this test script on it: it will write 0
// - place this test script on it again: it will write the correct data at last

int start() {
   for (int i = 0; i < 3; i++)
      Print(iClose("NZDUSD", PERIOD_M15, 0));
   return(0);
}
Simon Gniadkowski
17411

You can check for error 4066

ERR_HISTORY_WILL_UPDATED4066Requested history data in updating state.
erzo
109
erzo  

Thank you, I tried it, first time it creates a 4066 error as above, and after that creates this:

ERR_INCORRECT_SERIES_ARRAY_USING4054Incorrect series array using.


Is there any known way to handle this error, for example force reloading? Or I can only write the error and stop?

erzo
109
erzo  

I found a way to handle this last error, waiting only for the refreshing :) It can be useful when using Multi Timeframe (but only for regular timeframes).

#include <stderror.mqh>

int start() {
   if (iClose("NZDUSD", PERIOD_M15, 0) == 0.0) {
      int lastError = GetLastError();
      while (lastError == ERR_HISTORY_WILL_UPDATED || lastError == ERR_INCORRECT_SERIESARRAY_USING) {
         Sleep(1000);
         if (iClose("NZDUSD", PERIOD_M15, 0) > 0.0)
            break;
         lastError = GetLastError();
      }
   }

   Print(iClose("NZDUSD", PERIOD_M15, 0));
   return(0);
}
dabbler
1091
dabbler  

I would prefer it this way, so there is only one position for the test.

#include <stderror.mqh>

int start() {
   
   while( iClose("NZDUSD", PERIOD_M15, 0) == 0.0 ){
      int lastError = GetLastError();
      if( lastError != ERR_HISTORY_WILL_UPDATED && lastError != ERR_INCORRECT_SERIESARRAY_USING ){
         Print("Fatal Error " + lastError);
         return( 0 );
      }
      Sleep(1000);
   }

   Print(iClose("NZDUSD", PERIOD_M15, 0));
   return(0);
}
tesforex
39
tesforex  
erzo:

Thank you, I tried it, first time it creates a 4066 error as above, and after that creates this:

ERR_INCORRECT_SERIES_ARRAY_USING4054Incorrect series array using.


Is there any known way to handle this error, for example force reloading? Or I can only write the error and stop?


I had the same problem. Looks the history data were updated ramdomly. Still looking for a solution to this. Can anybody shed some light on this problem?