Всем привет. Попался мне на глаза скрипт, каторый синхранизирует историю по указанным пользователем инструментам. Скрипт рабочий вроде. Историю синхронизирует, пишет в файл, на графиках история отображается нормально. Но вот когда все синхронизировалось и делаешь потиковый тест эксперта в тестере. (галочка пересчитать стоит), тестер отказывается тестить систему. Пишет: 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]);
}
//---------------------------------------------------
Попался мне на глаза скрипт, каторый синхранизирует историю по указанным пользователем инструментам. Скрипт рабочий вроде. Историю синхронизирует, пишет в файл, на графиках история отображается нормально. Но вот когда все синхронизировалось и делаешь потиковый тест эксперта в тестере. (галочка пересчитать стоит), тестер отказывается тестить систему.
Пишет:
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 марта.