Скачать MetaTrader 5

Синхранизация "дыр" в истории.

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Добавляй наш канал в друзья и следи за новостями!
Forex Trader
114255
Forex Trader 2006.03.24 08:43 
Всем привет.
Попался мне на глаза скрипт, каторый синхранизирует историю по указанным пользователем инструментам. Скрипт рабочий вроде. Историю синхронизирует, пишет в файл, на графиках история отображается нормально. Но вот когда все синхронизировалось и делаешь потиковый тест эксперта в тестере. (галочка пересчитать стоит), тестер отказывается тестить систему.
Пишет:
2006.03.24 09:39:31 Tester: no data for testing
2006.03.24 09:39:31 TestGenerator: invalid file for 'EURUSD60'

В чем может быть проблема, мне не понятно. Если есть идеи прошу откликнуться. Ниже код скрипта.
Да еще MT4 buils 191 от 8 марта.

//+------------------------------------------------------------------+
//|                                                   dehole_hst.mq4 |
//|                                                   kukan&alextron |
//|                                              http://www.kukan.ru |
//+------------------------------------------------------------------+
//8 декабря 2005г 
//
//Скрипт выполнен для решения задач по выводу нескольких инструментов в одно окно, 
//и для синхронного совместного использования. Котировщики, (в частности Альпари) 
//используют следующий принцип поставки котировок, если нет изменения цены на каком-то баре, 
//то этот бар не поставляется. Особенно это касается мелких тайм фреймов 1 мин,  5мин…
//В ночное время , когда активность рынка низкая,  бывают выпадают несколько баров подряд.
//Для  одной валюты это не принципиально, но для вывода на экран одновременно нескольких 
//валют или индикаторов, связанных с валютами и анализа их, это становится актуально.
//С течением времени под   баром с определенным временем одной валюты,  стоит бар с другим 
//временем другой валюты, другими словами происходит рассинхронизация валют.
//Кроме того,   ряд индикаторов, запуск которых осуществляется от определенного времени  (бара), 
//не корректно работают, так как в это время для запуска может не оказаться бара.
//Так же с помощью его можно находить крупные дыры в исторических файлах.
//
//Скрипт делает новые файлы истории *.new, которые можно переименовать в *.hst, и перезапустив
//терминал, иметь синхронизированную по времени историю.
//Не забудь сохранить оригинальные файлы
//
//сразу моменты:
//!находим пару с самой маленькой историей и с этого момента пойдет склейка
//!соответственно размер истории будет определяться самой маленькой историей
//!важно, склеивание идет не по времени, а по существующим барам, т.е.
//полная синхронизация инструментов по времени
//журнал работы по паре смотреть в файле *.log в дирректории где хранятся
//файлы истории
//
//это скрипт, положить в дирректорию скриптов.
//запускать можно на любом графике, он графиками не пользуется
//обработает историю и уйдет.
//
#property copyright "kukan&alextron"
#property link      "http://www.kukan.ru"
#property show_inputs

#define  qty_smb  6     //количество инструментов

extern   int      m_period=1;          //можно клеить не только минутные бары - любые
extern   string   symbol_0="EURUSD";   //поставить в "входные параметры" "N" чтоб исключить пару из синхронизации
extern   string   symbol_1="GBPUSD";
extern   string   symbol_2="AUDUSD";
extern   string   symbol_3="USDCHF";
extern   string   symbol_4="USDJPY";
extern   string   symbol_5="USDCAD";   //можно другие инструменты обрабатывать
extern   int      volume_null=0;       //чем заполняем пустые бары

//массив названий инструментов
string   symbol_m[qty_smb];
//массивы указателей
int      i_handle[qty_smb];
int      o_handle[qty_smb];
int      log_handle[qty_smb];
//массив переменных - данные истории
int      h_time[qty_smb];
double   h_open[qty_smb],h_low[qty_smb],h_high[qty_smb],h_close[qty_smb];
double   h_volume[qty_smb];
double   old_close[qty_smb];     //старая цена инструмента
int      old_time[qty_smb];      //старенькая дата для журнальчика
bool     symbol_list[qty_smb];   //наличие инструмента
//массив статистических данных для работы с логом
int      lg_sk[qty_smb];   //пропущенных котировок всего
int      lg_sk_v[qty_smb]; //пропущенных котировок подряд
int      tm_cur=0;         //время бара обрабатываемой истории в секундах
int      ia,ib;            //переменные просто
int      cnt_bars=0;       //счетчик обработанных баров
bool     fl_stop=false;     //флаг останова скрипта
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//---- 
//открываем все файлы истории
for   (int i=0;i<qty_smb;i++)
   {
   //открытие файлов доноров
   i_handle[i]=FileOpenHistory(symbol_m[i]+m_period+".hst",FILE_BIN|FILE_READ);
   symbol_list[i]=true;
   if(i_handle[i]<0) 
      {
      Print(symbol_m[i]," Нехватает самой истории, исключаем из работы");
      h_time[i]=-1;  //будем пропускать данный инструмент
      symbol_list[i]=false;
      }
      else
      {
      fl_stop=true;
      }
   //открытие файлов назначений
   if (h_time[i]>=0 && symbol_list[i])
      {
      o_handle[i]=FileOpenHistory(symbol_m[i]+m_period+".new",FILE_BIN|FILE_WRITE);
      if(o_handle[i]<0) return(-1);
      log_handle[i]=FileOpenHistory(symbol_m[i]+m_period+".log",FILE_BIN|FILE_WRITE);
      if(o_handle[i]<0) return(-1);
      //переписывание заголовка исторического файла
      copy_title_proc(i_handle[i],o_handle[i]);
      }
   }
//проверка если нет ниодной истории то выйти нахрен
if (!fl_stop)
   {
   Print(" Нет таких историй");
   return(-1);
   }
//все готово файлы открыты
//ищем самую короткую историю
tm_cur=0;     //возмем какое нибудь старое время
for   (i=0;i<qty_smb;i++)
   {
   if (h_time[i]<0)  continue;   //пропускаем инструмент
   read_bars_hst(i);
   if (h_time[i]==0)
      {
      Print(symbol_m[i]," Нехватает самой истории, исключаем из работы");
      h_time[i]=-1;     //будем пропускать данный инструмент
      symbol_list[i]=false;
      }
   if (tm_cur<h_time[i])
      {
      tm_cur=h_time[i];
      ia=i;             //запоминаем номер инструмента с самой короткой историей
      }
   old_time[i]=h_time[i];     //убирание пограничных эфектов
   old_close[i]=h_close[i];
   }
cnt_bars++;
Print("Самая короткая история у ",symbol_m[ia]," с ",TimeToStr(h_time[ia],TIME_DATE|TIME_MINUTES));
//
//теперь устанавливаем файловые указатели на данное время по всем инструментам
//вернее на время после этого на один бар
for   (i=0;i<qty_smb;i++)
   {
   if (h_time[i]<0)  continue;   //пропускаем инструмент
   while (tm_cur>h_time[i])
      {
      if (h_time[i]==0) 
         {//если файл кончился присылается 0 и это гуд, 
         //не буду пока обрабатывать конец файла
         //если файл кончился тут, то нехватает данных на инструменте 
         //в той истории где вопщето мы должны клеить
         Print(symbol_m[i]," Нехватает данных в ранней истории, исключаем из работы ");
         h_time[i]=-1;  //будем пропускать данный инструмент
         symbol_list[i]=false;
         break;
         }
      read_bars_hst(i);
      }
   write_text_logs(i,"Начало работы\t "+TimeToStr(tm_cur,TIME_DATE|TIME_MINUTES)+"\n");
   }
//..................................................
//все файлы синхронизированы основной цикл склейки
//если время меньше то пишем в выходной файл цену закрытия с нулевым обьемом
//и редактируем журнал
//теперь если файл кончился уже не будем пропускать инструмент
while (fl_stop)
   {
   //заполняем новый файл истории записями
   for   (i=0;i<qty_smb;i++)
      {
      if (symbol_list[i])  //если работать не начали то и нехрен придумывать
         {
         if (tm_cur<h_time[i] || h_time[i]<0)
            {//нет такого бара на инструменте или вообще кончился файл инструмента
            write_bars_hst_null(i); //придумываем его
            lg_sk[i]++;             //считаем придуманные бары
            lg_sk_v[i]++;           //считаем придуманные бары подряд
            }
            else
            {//такой бар есть копируем
            write_bars_hst(i);
            if (lg_sk_v[i]!=0)
               {
               //Однако пропущенные бары есть делаем запись в журнал
               write_text_logs(i,"Нет баров-"+lg_sk_v[i]+"\t "+TimeToStr(old_time[i],TIME_DATE|TIME_MINUTES)+"\n");
               lg_sk_v[i]=0;
               }            
            }
         }
      }
   //теперь находим следующий сушествующий на каком либо инструменте бар
   //бар должен быть самым старым
   //для этого считываем по одной записи с инструмента
   //у которого время меньше или равно только что обработанному
   //
   ib=CurTime();  //просто взял молодое время :)
   for   (i=0;i<qty_smb;i++)
      {
      if (h_time[i]<0)  continue;   //пропускаем инструмент
      if (h_time[i]<=tm_cur) read_bars_hst(i);
      if (h_time[i]==0) 
         {
         Print(symbol_m[i]," Кончился файл истории ",TimeToStr(old_time[i],TIME_DATE|TIME_MINUTES));
         write_text_logs(i,"Кончился файл истории \t "+TimeToStr(old_time[i],TIME_DATE|TIME_MINUTES)+
         "\t синхронизировал "+cnt_bars+" баров\n");
         h_time[i]=-1;  //будем пропускать данный инструмент
         }
         else
         {//бар есть
         //если он старее ib, то ib будет равен ему
         if (ib>h_time[i]) ib=h_time[i];
         }
      }
   cnt_bars++;
   //теперь присваиваем текущему времени самое старое из прочитанных
   tm_cur=ib;
   //
   //проверяем не пора ли закончить тосить историю
   //если не осталось ни одного файла донора
   fl_stop=false;
   for   (i=0;i<qty_smb;i++)
      {
      if (h_time[i]>0)  fl_stop=true;  //кто то живой остался :))
      }
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+
int init()
  {
   symbol_m[0]=symbol_0;
   symbol_m[1]=symbol_1;
   symbol_m[2]=symbol_2;
   symbol_m[3]=symbol_3;
   symbol_m[4]=symbol_4;
   symbol_m[5]=symbol_5;
   //
   ArrayInitialize(i_handle,-1);
   ArrayInitialize(o_handle,-1);
   ArrayInitialize(log_handle,-1);
   ArrayInitialize(h_time,0);
   ArrayInitialize(lg_sk,0);
   ArrayInitialize(lg_sk_v,0);
  }
//+------------------------------------------------------------------+
void deinit()
  {
   //закрываем открытые файлы при выходе из скрипта
for   (int i=0;i<qty_smb;i++)
   {
   if(i_handle[i]>=0) { FileClose(i_handle[i]); i_handle[i]=-1; }       //файлы источники
   if(o_handle[i]>=0) { FileClose(o_handle[i]); o_handle[i]=-1; }       //файлы назначения
   if(log_handle[i]>=0) { FileClose(log_handle[i]); log_handle[i]=-1; } //файлы журналов
   }
   Print("Работать закончил, синхронизировал "+cnt_bars+" баров ");
   //
  }
//+------------------------------------------------------------------+
//процедура копирования заголовка исторического файла
//похоже это зря в процедуру оформил, фиг с ним
bool  copy_title_proc(int i_handle,int o_handle)
   //на входе указатели файла донора и куда
   {
   int    i_unused[13];
   //
   FileWriteInteger(o_handle,FileReadInteger(i_handle,LONG_VALUE),LONG_VALUE);   //версия
   //
   FileWriteString(o_handle,FileReadString(i_handle,64), 64);  //копирайт
   FileWriteString(o_handle,FileReadString(i_handle,12), 12);  //символ
   //
   FileWriteInteger(o_handle,FileReadInteger(i_handle,LONG_VALUE),LONG_VALUE);   //период
   FileWriteInteger(o_handle,FileReadInteger(i_handle,LONG_VALUE),LONG_VALUE);   //количество знаков после точки
   FileWriteInteger(o_handle,FileReadInteger(i_handle,LONG_VALUE),LONG_VALUE);   //незнаю
   FileWriteInteger(o_handle,FileReadInteger(i_handle,LONG_VALUE),LONG_VALUE);   //незнаю
   //
   FileReadArray(i_handle,i_unused,0,13);
   FileWriteArray(o_handle,i_unused,0,13);   //незнаю
   //
   FileFlush(o_handle);
   //
   return(true);
   }
//+------------------------------------------------------------------+
//чтение одной записи из файла истории в массив
void  read_bars_hst(int number)
   //number-номер инструмента
   {
   old_time[number]=h_time[number];       //запоминаем дату для журнальчика
   old_close[number]=h_close[number];     //запоминаем предыдущую цену
   h_time[number]=FileReadInteger(i_handle[number],LONG_VALUE);
   //
   h_open[number]=FileReadDouble(i_handle[number],DOUBLE_VALUE);
   h_low[number]=FileReadDouble(i_handle[number],DOUBLE_VALUE);
   h_high[number]=FileReadDouble(i_handle[number],DOUBLE_VALUE);
   h_close[number]=FileReadDouble(i_handle[number],DOUBLE_VALUE);
   h_volume[number]=FileReadDouble(i_handle[number],DOUBLE_VALUE);
   //
   }
//+------------------------------------------------------------------+
//запись одного бара в файл истории
void   write_bars_hst(int number)
   {
   FileWriteInteger(o_handle[number],h_time[number],LONG_VALUE);
   //
   FileWriteDouble(o_handle[number],h_open[number],DOUBLE_VALUE);
   FileWriteDouble(o_handle[number],h_low[number],DOUBLE_VALUE);
   FileWriteDouble(o_handle[number],h_high[number],DOUBLE_VALUE);
   FileWriteDouble(o_handle[number],h_close[number],DOUBLE_VALUE);
   FileWriteDouble(o_handle[number],h_volume[number],DOUBLE_VALUE);
   //
   FileFlush(o_handle[number]);
   //
   }
//---------------------------------------------------
//запись одного пустого бара в файл истории
void   write_bars_hst_null(int number)
   {
   FileWriteInteger(o_handle[number],tm_cur,LONG_VALUE);
   //
   FileWriteDouble(o_handle[number],old_close[number],DOUBLE_VALUE);
   FileWriteDouble(o_handle[number],old_close[number],DOUBLE_VALUE);
   FileWriteDouble(o_handle[number],old_close[number],DOUBLE_VALUE);
   FileWriteDouble(o_handle[number],old_close[number],DOUBLE_VALUE);
   FileWriteDouble(o_handle[number],volume_null,DOUBLE_VALUE);
   //
   FileFlush(o_handle[number]);
   //
   }
//процедура записи в журнал
void  write_text_logs(int number,string text)
   {
   FileWriteString(log_handle[number],text,StringLen(text));
   FileFlush(log_handle[number]);
   }
//---------------------------------------------------
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий