Заголовки и MqlRates в файле истории MT4

 

Есть ли какой то поясняющий материал по заголовкам хистори файлов, кручу верчу, уже на самом деле просто вообще перестал что то понимать, статью вроде прочитал про оффлайн графики, как то не сильно помогла

создаю файл, пишу заголовки, добавляю один бар с нулём

всё, пробую прочитать последний бар , хрен там, 

пробовал добавить заголовок структурой, прочитать его же - тоже хрен там

вообще как из HST файла что то вытащить и как в него правильно писать 

где ошибка то ? пример вроде простой - скрипт

#property version   "1.00"
#property strict

int HstHandle = -1;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
MakeNewFile("BTCUSD_1",20); // создали
UpdateHst("BTCUSD_1",20); // читаем
   
  }
//+------------------------------------------------------------------+
int MakeNewFile(string ChartName0, int curPeriod0){
   MqlRates rate;
   string fname = ChartName0+IntegerToString(curPeriod0)+".hst";
   HstHandle=FileOpenHistory(fname,FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI);//
   if(HstHandle<0){ // не смогли создать
      Print("Error: can\'t create / open history file: "+(string)GetLastError()+": "+fname);
      return(0);
   }else{ // есть файл - создали
      int      file_version=401;
      string   c_copyright="(C)opyright 2003, MetaQuotes Software Corp.";
      string   c_symbol = ChartName0;
      int      i_period = curPeriod0;
      int      i_digits = 6;
      int      i_unused[13];
      ArrayInitialize(i_unused,0);
   //--- write history file header
      FileWriteInteger(HstHandle,file_version,LONG_VALUE);
      FileWriteString(HstHandle,c_copyright,64);
      FileWriteString(HstHandle,c_symbol,12);
      FileWriteInteger(HstHandle,i_period,LONG_VALUE);
      FileWriteInteger(HstHandle,i_digits,LONG_VALUE);
      FileWriteInteger(HstHandle,0,LONG_VALUE);
      FileWriteInteger(HstHandle,0,LONG_VALUE);
      FileWriteArray(HstHandle,i_unused,0,13);
   
      rate.time = (datetime)0;      rate.open = 0.0;   rate.low = 0.0;        rate.high = 0.0;
      rate.close = 0.0;    rate.tick_volume = 0;   rate.spread = 0;        rate.real_volume = 0;
      FileWriteStruct(HstHandle,rate);
   }
   FileFlush(HstHandle);
   FileClose(HstHandle);
   
   return(1);
}

int UpdateHst(string ChartName0, int curPeriod0){
   MqlRates rate, rateSourse;
   
   string fname = ChartName0+IntegerToString(curPeriod0)+".hst";
   HstHandle=FileOpenHistory(fname,FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI|FILE_BIN); 
   
   if(HstHandle<0){ // несмогли создать
      Print("Error: can\'t create / open history file: "+(string)GetLastError()+": "+fname);
      return(0);
   }else{ // есть файл - создали
    // только обновляем нехватающие бары
 
      FileSeek(HstHandle,FileSize(HstHandle)-sizeof(MqlRates),SEEK_END);
      
      FileReadStruct(HstHandle, rateSourse,sizeof(MqlRates));
      
      Print("Struct = "+(string)rateSourse.time+" open "+(string)rateSourse.open);
      
   }
   return(0);
}

выдает всё что угодно но не бар 

2018.11.28 01:23:53.799 Hist EURAUD,H1: Struct = 2042.08.21 11:57:57 open 1.490199165398506e-254
2018.11.28 01:23:53.797 Hist EURAUD,H1: initialized

а при след. запуске 

2018.11.28 01:32:02.106 Hist EURAUD,H1: Struct =  open 1.13275585698096e-314
2018.11.28 01:32:02.099 Hist EURAUD,H1: initialized

Раньше не обращал внимание на заголовки, типа импортировалось и ладно , но появляются двойные свечи, после которых после пересчета графика все цены почему то округляются автоматом , пытаюсь что то вытащить или найти хвост последней свечи , не получается

Файлы:
Hist.mq4  7 kb
 

пол дня мозговыноса и что то типа такого получилось

#property strict
#include <WinUser32.mqh>
int HstHandle = -1;
bool lock = false;
struct HistoryHeader
  {
   int               version;
   uchar             copyright[64];
   uchar             symbol[12];
   int               timeFrame;
   int               digits;
   int               reserved1;
   int               reserved2;
   int               unused[13];
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---

      string Sym = "BTCUSD_1"; int Per = 20;
      lock = true;
      MakeNewFile(Sym,Per);
      lock = false;
      int hwnd=WindowHandle(Sym, Per);
      if(!lock&& _Symbol==Sym){ CheckFile(Sym,Per,true); }
       //
      if(hwnd>0){ PostMessageA(hwnd,WM_COMMAND,33324,0); }
   
  }
//+------------------------------------------------------------------+
int MakeNewFile(string ChartName0, int curPeriod0){
   MqlRates rate;
   string fname = ChartName0+IntegerToString(curPeriod0)+".hst";
   HstHandle=FileOpenHistory(fname,FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI);//
   if(HstHandle<0){ // несмогли создать
      Print("Error: can\'t create / open history file: "+(string)GetLastError()+": "+fname);
      return(0);
   }else{ // есть файл - создали
      HistoryHeader historyHeader={401,
        {
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        }
         ,
        {0,0,0,0,0,0,0,0,0,0,0,0},0,0,0,0,{0,0,0,0,0,0,0,0,0,0,0,0,0}
     };
   StringToCharArray("(C)opyright 2003, MetaQuotes Software Corp.",historyHeader.copyright);
   StringToCharArray(ChartName0,historyHeader.symbol);
   historyHeader.timeFrame=(int)curPeriod0;
   historyHeader.digits=6;
   FileWriteStruct(HstHandle,historyHeader);
      rate.time = 0;      rate.open = 0;   rate.low = 0;        rate.high = 0;
      rate.close = 0;    rate.tick_volume = 0;   rate.spread = 0;        rate.real_volume = 0;
      FileWriteStruct(HstHandle,rate);
   }
   FileFlush(HstHandle);
   FileClose(HstHandle);
   
   return(1);
}

int CheckFile(string ChartName0, int curPeriod0, bool logir = true){
   MqlRates rate[], rateSourse; HistoryHeader historyHeader; 

   string fname = ChartName0+IntegerToString(curPeriod0)+".hst";
   HstHandle=FileOpenHistory(fname,FILE_BIN|FILE_READ|FILE_SHARE_READ|FILE_ANSI); 
   
   if(HstHandle==INVALID_HANDLE){ // несмогли создать
      if(logir)Print("Error: can\'t create / open history file: "+(string)GetLastError()+": "+fname);
      return(0);
   }else{ // есть файл - создали
      if(logir)Print("h = "+(string)HstHandle);
      int hBit = FileReadStruct(HstHandle, historyHeader, sizeof(HistoryHeader));
      ulong lastBit = FileTell(HstHandle);
      if(logir)Print("Header Struct = "+CharArrayToString(historyHeader.copyright)+" open "+CharArrayToString(historyHeader.symbol));
      //FileSeek(HstHandle,FileSize(HstHandle)-sizeof(MqlRates),SEEK_SET);
      
      int cntRates = (int)(FileSize(HstHandle)-sizeof(HistoryHeader))/sizeof(MqlRates);
      int copied = -1;
      if(ArrayResize(rate,cntRates)<0){
         if(logir)Print("Не хватит памяти для копирования котировок"); // будем просто дописывать последний бар
      }else{
         copied=CopyRates(ChartName0,curPeriod0,0,cntRates,rate); // сколько скопировали
      }
      
      if(logir)Print("всего баров = "+(string)cntRates+"  copied="+(string)copied);
      if(copied<1){ // не смогли скопировать котировки , придется читать из файла
         if(logir)Print("ошибка копирования "+(string)GetLastError());
         if(cntRates<2){ // Новёхонький 1 бар
            FileReadStruct(HstHandle, rateSourse, sizeof(MqlRates));
            if(rateSourse.time<1){ // первая свеча с нулевым временем 
               FileSeek(HstHandle, lastBit, SEEK_SET); // пишем от заголовка
            }else{
               FileSeek(HstHandle, lastBit, SEEK_SET); // пишем от заголовка
            }
         }else{ // Есть что то больше чем 1 бар
            FileSeek(HstHandle, FileSize(HstHandle)-sizeof(MqlRates), SEEK_END); // пишем вместо последнего бара - но узнаем его дату
            FileReadStruct(HstHandle, rateSourse, sizeof(MqlRates)); // читаем последний бар
            
            
         }
         if(logir)Print("Cute Struct = "+rateSourse.time+" open "+(rateSourse.open)+" close "+(rateSourse.close));
      }else{ // смогли скопировать/ в теории у нас массив rate целиком, поэлементно 
         
         if(logir)Print("Struct 0= "+(string)rate[0].time+" open "+(string)rate[0].open);
         if(logir)Print("Struct 1= "+(string)rate[1].time+" open "+(string)rate[1].open);
      }
      
      
   }
   FileClose(HstHandle);
   return(0);
}

получается иногда он может копировать CopyRates а иногда может  только выдирать из файла, причем только если открыт сам график

Причина обращения: