The problem is that this script does not do its job after the last update of mt. bars are still missing.
maybe you can tweak it for a new platform? Or maybe there is another similar and working solution. search does not return any results.
thanks in advance.
//+------------------------------------------------------------------+//| 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//количество инструментовexternint m_period= 1 ; //можно клеить не только минутные бары - любыеexternstring symbol_0= "EURUSD" ; //поставить в "входные параметры" "N" чтоб исключить пару из синхронизацииexternstring symbol_1= "GBPUSD" ;
externstring symbol_2= "AUDUSD" ;
externstring symbol_3= "USDCHF" ;
externstring symbol_4= "USDJPY" ;
externstring symbol_5= "USDCAD" ; //можно другие инструменты обрабатыватьexternint 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 );
return ( 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 wi_handle, int wo_handle)
//на входе указатели файла донора и куда
{
int i_unused[ 13 ];
//FileWriteInteger (wo_handle, FileReadInteger (wi_handle, LONG_VALUE ), LONG_VALUE ); //версия//FileWriteString (wo_handle, FileReadString (wi_handle, 64 ), 64 ); //копирайтFileWriteString (wo_handle, FileReadString (wi_handle, 12 ), 12 ); //символ//FileWriteInteger (wo_handle, FileReadInteger (wi_handle, LONG_VALUE ), LONG_VALUE ); //периодFileWriteInteger (wo_handle, FileReadInteger (wi_handle, LONG_VALUE ), LONG_VALUE ); //количество знаков после точкиFileWriteInteger (wo_handle, FileReadInteger (wi_handle, LONG_VALUE ), LONG_VALUE ); //незнаюFileWriteInteger (wo_handle, FileReadInteger (wi_handle, LONG_VALUE ), LONG_VALUE ); //незнаю//
FileReadArray(wi_handle,i_unused, 0 , 13 );
FileWriteArray (wo_handle,i_unused, 0 , 13 ); //незнаю//FileFlush (wo_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]);
}
//---------------------------------------------------
I found the problem. ObjectGet gives out zero instead of time and colour. It is written in warnings too, after I set it: possible loss of data due to type conversion. So what to do? How to fix it to give out what I need?
upd: ObjectGetInteger gives out all right. Been racking my brain for a week...
is there any way to save the loading parameters of a custom indicator (which are initialized via input ... in the code header) and then load them, similar to how this is done when testing EAs?
Good afternoon,
I get a warning during compilation
possible loss of data due to type conversion
on the line:
int Stop_Loss = MarketInfo(Symbol(),MODE_STOPLEVEL);
The description of MarketInfo says that it returns type double.
But the stop level is an integer and I want to use it
as an integer...
..Is it the developers' fault, or is the warning correct and I don't understand it?
Good afternoon.
Can you tell me which broker has the minimum delay (ping) on MT4?
The question is off-topic, we don't discuss brokers here. You don't need to ask a question twice in two forums.
Sorry)
The question is off-topic, we don't discuss brokers here. You don't need to ask a question twice in two forums.
dear programmers, please help!!!
The problem is that this script does not do its job after the last update of mt. bars are still missing.
maybe you can tweak it for a new platform? Or maybe there is another similar and working solution. search does not return any results.
thanks in advance.
Dear programmers, help please!!!
the problem is that this script doesn't work after the last mt update. the bars are still missing.
can it be tweaked for the new platform? or maybe there's a similar and workable solution.
thanks in advance.
Where can I download this script, I just don't know how to get all this code into a script so small?
Dear programmers, help please!!!
the problem is that this script doesn't work after the last mt update. the bars are still missing.
can it be tweaked for the new platform? or maybe there's a similar and workable solution.
thanks in advance.
Answers here
I found the problem. ObjectGet gives out zero instead of time and colour. It is written in warnings too, after I set it: possible loss of data due to type conversion. So what to do? How to fix it to give out what I need?
upd: ObjectGetInteger gives out all right. Been racking my brain for a week...
Hello,
is there any way to save the loading parameters of a custom indicator (which are initialized via input ... in the code header) and then load them, similar to how this is done when testing EAs?
I mean without writing your own utilities.
Thanks
I have started to get an error in this function in the library after the build update . The compiler points to the last line :
The error is as follows:
How can I fix it? I understand that for other cases the default output is needed. But I don't logically need it... How to fix it?