Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Кто-нибудь может пояснить, почему этот код не точно синхронизиоует время?
Ведь в премаркет приходит "свежая" котировка, с новым временем сервера(биржи).
Попробуй то что у меня получилось:
//| Sync_Time.mq5 |
//| Copyright 2016, Serj_Che |
//| https://www.mql5.com/ru/users/serj_che |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Serj_Che"
#property link "https://www.mql5.com/ru/users/serj_che"
#property version "1.00"
input bool info=true;
input int precision = 50;
//+------------------------------------------------------------------+
struct _SYSTEMTIME
{
short year;
short mon;
short day_of_week;
short day;
short hour;
short min;
short sec;
short msc;
};
_SYSTEMTIME loc_time;
#import "kernel32.dll"
void GetLocalTime(_SYSTEMTIME &sys_time);
bool SetLocalTime(_SYSTEMTIME &sys_time);
#import
//---
MqlTick tick;
MqlDateTime sv_time;
int tick_msc,ping,time_server,time_local,delta=0,mdelta[20],n=0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
Comment("");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
loc_time.year=0;
GetLocalTime(loc_time);
if(loc_time.year>0)
{
if(!SymbolInfoTick(_Symbol,tick)) { Print("error SymbolInfoTick",GetLastError()); return; }
ping=TerminalInfoInteger(TERMINAL_PING_LAST)/1000;
tick_msc=int(tick.time_msc%1000);
TimeToStruct(tick.time,sv_time);
time_server=(sv_time.sec+sv_time.min*60)*1000+tick_msc;
time_local=(loc_time.sec+loc_time.min*60)*1000+loc_time.msc;
delta=AvgDelta(time_server-time_local);
if(info) Comments();
if(MathAbs(delta)>1000)
{
loc_time.sec=(short)sv_time.sec;
loc_time.min=(short)sv_time.min;
CorrectTime(loc_time);
return;
}
if(delta>precision && loc_time.min<58)
{
loc_time.msc+=(short)delta;
if(loc_time.msc>=1000) { loc_time.msc-=1000; loc_time.sec+=1; }
if(loc_time.sec>=60) { loc_time.sec-=60; loc_time.min+=1; }
CorrectTime(loc_time);
}
if(delta<-precision && loc_time.min>1)
{
loc_time.msc+=(short)delta;
if(loc_time.msc<0) { loc_time.msc+=1000; loc_time.sec-=1; }
if(loc_time.sec<0) { loc_time.sec+=60; loc_time.min-=1; }
CorrectTime(loc_time);
}
}
else
{
Print("error GetLocalTime");
}
}
//+------------------------------------------------------------------+
int AvgDelta(int d)
{
int avgd=0;
mdelta[n]=d;
n++; if(n>=20) n=0;
for(int i=0;i<20;i++) avgd+=mdelta[i];
return(avgd/20);
}
//+------------------------------------------------------------------+
void CorrectTime(_SYSTEMTIME <ime)
{
if(SetLocalTime(ltime))
{
ArrayInitialize(mdelta,0);
Print("Local time sync -- is done, Sync min = ",ltime.min,
" Sync sec = ",ltime.sec," delta ms = ",delta);
}
else Print("error SetLocalTime");
}
//+------------------------------------------------------------------+
void Comments()
{
Comment(
"\n time server: ",sv_time.hour,": ",sv_time.min,": ",sv_time.sec,": ",tick_msc,
"\n time server: ",loc_time.hour,": ",loc_time.min,": ",loc_time.sec,": ",loc_time.msc,
"\n ping : ",ping,
"\n time_server : ",time_server,
"\n time___local : ",time_local,
"\n delta : ",delta,
"\n min max delta: ",mdelta[ArrayMaximum(mdelta)]," : ",mdelta[ArrayMinimum(mdelta)],
"");
}
//+------------------------------------------------------------------+
Время плавает из за пинга, задержек сервера и терминала. Но в пределах -10; +10; миллисекунд получается синхронизировать.
В премаркет тики тоже приходят.
Попробуй то что у меня получилось:
Время плавает из за пинга, задержек сервера и терминала. Но в пределах -10; +10; миллисекунд получается синхронизировать.
В премаркет тики тоже приходят.
Спасибо, попробую.
Добавлено
Выглядит не плохо, но
1. Если этот код вставить в торгового эксперта, то как синхронизировать коррекцию между экспертами, если
этот эксперт работает на нескольких фьючерсах?
2. Если поместить твой код в отдельного эксперта, то где гарантия, что OnTick придёт имеено
в этот символ в премаркет (может и не прийти)?
3. Почему OnTick() лучше, чем OnBookEvent() в премаркет?
Чем "правильнее"
нежели
Спасибо, попробую.
Добавлено
Выглядит не плохо, но
1. Если этот код вставить в торгового эксперта, то как синхронизировать коррекцию между экспертами, если
этот эксперт работает на нескольких фьючерсах?
2. Если поместить твой код в отдельного эксперта, то где гарантия, что OnTick придёт имеено
в этот символ в премаркет (может и не прийти)?
Советник лучше повесить на отдельный график наиболее ликвидный, на двух графиках могут мешать друг другу.
Когда синхронизируется лучше удалить, раз в сутки синхронизировать достаточно должно быть. Не могут же часы брокера, биржи или компьютера так сильно бежать или отставать.
Можно сделать чтобы советник сам удалялся когда синхронизируется.
Советник лучше повесить на отдельный график наиболее ликвидный, на двух графиках могут мешать друг другу.
Когда синхронизируется лучше удалить, раз в сутки синхронизировать достаточно должно быть. Не могут же часы брокера, биржи или компьютера так сильно бежать или отставать.
Можно сделать чтобы советник сам удалялся когда синхронизируется.
3. Почему OnTick() лучше, чем OnBookEvent() в премаркет?
Чем "правильнее"
нежели
я же объяснял уже, мы не можем получить время изменения стакана, такого функционала нет в терминале. Изменения стакана происходит не только когда изменяется Ask, Bid, Last, соответственно и время OnBookEvent() неизвестно.
можно получить только время тика.
OnTick() не лучше, чем OnBookEvent(), просто по другому не получится.
из соседней ветки:
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Сантимент: Tslab + plaza 2 против MT 5
Alexey Kozitsyn, 2017.01.17 12:02
Вы не поняли. Я в курсе структуры тика, к ней претензий нет. Претензии есть к тому, что в случае подписки на события обновления стакана, невозможно получить время прихода этого события, соответственно если я получил тики, а затем хочу узнать состояние стакана - я не могу этого сделать, т.к. времени прихода стакана нет! Синхронизацию провести невозможно! Аналогично с другими биржевыми показателями, которые привел в предыдущем посте.
И мой вопрос заключался в том, когда будет добавлено время прихода события стакана + других биржевых показателей, таких как ОИ.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Сантимент: Tslab + plaza 2 против MT 5
Renat Fatkhullin, 2017.01.17 14:01
Подумаемя же объяснял уже, мы не можем получить время изменения стакана, такого функционала нет в терминале. Изменения стакана происходит не только когда изменяется Ask, Bid, Last, соответственно и время OnBookEvent() неизвестно.
можно получить только время тика.
OnTick() не лучше, чем OnBookEvent(), просто по другому не получится.
Серёж!
Смотри. Пришла новая котировка, стакан изменился, следовательно должно прийти событие OnBookEvent(),
которое мы просто используем как СОБЫТИЕ.
Затем, нет никакой разницы как ты получаешь инфу о тике через if(!SymbolInfoTick(_Symbol,tick)) { Print("error SymbolInfoTick",GetLastError()); return; }
или if(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)
Но разница в моём подходе и твоём огромная.
В моём случае, используя эксперта на малоликвидном инструменте (например UUAH) ты можешь добавить стаканы ВСЕХ фьючерсов и
ГАРАНТИРОВАННО получишь тик в премаркет, не думая о работе других экспертов в терминале.
Т.е все новые котировки будут "идти" в отдельный советник.
Добавлено
который будет "заниматься" только синхронизацией, не мешая никому.
//| Time_sync_forts.mq5 |
//| Copyright 2017 prostotrader |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017 prostotrader"
#property link "https://www.mql5.com"
#property version "1.01"
//---
struct _SYSTEMTIME
{
ushort wYear;
ushort wMonth;
ushort wDayOfWeek;
ushort wDay;
ushort wHour;
ushort wMinute;
ushort wSecond;
ushort wMilliseconds;
};
_SYSTEMTIME loc_time;
#import "kernel32.dll"
void GetLocalTime(_SYSTEMTIME &sys_time);
bool SetLocalTime(_SYSTEMTIME &sys_time);
#import
//---
bool is_sync;
string symb_rts;
string symb_si;
string symb_gold;
string symb_br;
string symb_gazr;
string symb_sbrf;
datetime last_time;
//
input string BrInstr="BR-2.17"; //Brent
//+------------------------------------------------------------------+
//| Expert set second symbol function |
//+------------------------------------------------------------------+
string SetSecSymbol(const string a_symbol,const string prefix)
{
int str_tire=0;
ushort let_symbol;
int str_size=StringLen(a_symbol);
for(int i=0; i<str_size; i++)
{
let_symbol=StringGetCharacter(a_symbol,i);
if(let_symbol=='-')
{
str_tire=i;
break;
}
}
if(str_tire>0)
{
return(prefix + StringSubstr(a_symbol, str_tire, str_size - str_tire));
}
return("");
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
last_time=TimeCurrent();
is_sync=false;
MarketBookAdd(Symbol());
//---
symb_rts=SetSecSymbol(Symbol(),"RTS");
if(!SymbolSelect(symb_rts,true))
{
MessageBox(symb_rts+" not found in the Market watch!","Error",MB_OK|MB_ICONERROR);
return(INIT_FAILED);
}
else MarketBookAdd(symb_rts);
//---
symb_si=SetSecSymbol(Symbol(),"Si");
if(!SymbolSelect(symb_si,true))
{
MessageBox(symb_si+" not found in the Market watch!","Error",MB_OK|MB_ICONERROR);
return(INIT_FAILED);
}
else MarketBookAdd(symb_si);
//---
symb_gold=SetSecSymbol(Symbol(),"GOLD");
if(!SymbolSelect(symb_gold,true))
{
MessageBox(symb_gold+" not found in the Market watch!","Error",MB_OK|MB_ICONERROR);
return(INIT_FAILED);
}
else MarketBookAdd(symb_gold);
//---
symb_gazr=SetSecSymbol(Symbol(),"GAZR");
if(!SymbolSelect(symb_gazr,true))
{
MessageBox(symb_gazr+" not found in the Market watch!","Error",MB_OK|MB_ICONERROR);
return(INIT_FAILED);
}
else MarketBookAdd(symb_gazr);
//---
symb_sbrf=SetSecSymbol(Symbol(),"SBRF");
if(!SymbolSelect(symb_sbrf,true))
{
MessageBox(symb_sbrf+" not found in the Market watch!","Error",MB_OK|MB_ICONERROR);
return(INIT_FAILED);
}
else MarketBookAdd(symb_sbrf);
//---
symb_br=BrInstr;
if(!SymbolSelect(symb_br,true))
{
MessageBox(symb_br+" not found in the Market watch!","Error",MB_OK|MB_ICONERROR);
return(INIT_FAILED);
}
else MarketBookAdd(symb_br);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
MarketBookRelease(Symbol());
MarketBookRelease(symb_rts);
MarketBookRelease(symb_br);
MarketBookRelease(symb_si);
MarketBookRelease(symb_gold);
MarketBookRelease(symb_gazr);
MarketBookRelease(symb_sbrf);
}
//+------------------------------------------------------------------+
//| Expert Convert To Time function |
//+------------------------------------------------------------------+
bool ConvertToTime(const long n_value,_SYSTEMTIME &a_time)
{
a_time.wMilliseconds=ushort(n_value%1000);
ulong new_time=ulong(double(n_value)/1000);
MqlDateTime cur_time = {0};
TimeToStruct(datetime(new_time),cur_time);
if(cur_time.year>0)
{
a_time.wDay=ushort(cur_time.day);
a_time.wDayOfWeek=ushort(cur_time.day_of_week);
a_time.wHour=ushort(cur_time.hour);
a_time.wMinute= ushort(cur_time.min);
a_time.wMonth = ushort(cur_time.mon);
a_time.wSecond= ushort(cur_time.sec);
a_time.wYear=ushort(cur_time.year);
return(true);
}
return(false);
}
//+------------------------------------------------------------------+
//| Expert On book event function |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
loc_time.wYear=0;
GetLocalTime(loc_time);
if(loc_time.wYear>0)
{
if((loc_time.wHour==9) && (loc_time.wMinute>=50) && (loc_time.wMinute<=59))
{
MqlTick curr_tick[1];
if(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)
{
MqlDateTime sv_time;
TimeToStruct(curr_tick[0].time,sv_time);
if(!is_sync)
{
if((loc_time.wDayOfWeek==ushort(sv_time.day_of_week)) &&
(loc_time.wHour==ushort(sv_time.hour)))
{
long last_ping=long(NormalizeDouble((double(TerminalInfoInteger(TERMINAL_PING_LAST))/1000)/2,0));
long mls_time=long(curr_tick[0].time_msc%1000);
if((mls_time+last_ping)>999)
{
mls_time=long(curr_tick[0].time_msc)+last_ping;
if(!ConvertToTime(mls_time, loc_time)) return;
}
else
{
loc_time.wMinute = ushort(sv_time.min);
loc_time.wSecond = ushort(sv_time.sec);
loc_time.wMilliseconds=ushort(mls_time);
}
if(SetLocalTime(loc_time))
{
is_sync=true;
Print("Local time sync is done. Symbol = ", symbol, " Sync min = ", loc_time.wMinute,
" Sync sec = ", loc_time.wSecond, " Sync ms = ", loc_time.wMilliseconds);
}
}
}
}
}
else is_sync=false;
}
}
//+------------------------------------------------------------------+
Вот только, сегодня, после 10-00 (синхронихация была в премаркет)
локальное время отличалось от времени в Обзоре рынка на 7 сек. :(
Серёж!
Смотри. Пришла новая котировка, стакан изменился, следовательно должно прийти событие OnBookEvent(),
которое мы просто используем как СОБЫТИЕ.
Затем, нет никакой разницы как ты получаешь инфу о тике через if(!SymbolInfoTick(_Symbol,tick)) { Print("error SymbolInfoTick",GetLastError()); return; }
или if(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)
Но разница в моём подходе и твоём огромная.
В моём случае, используя эксперта на малоликвидном инструменте (например UUAH) ты можешь добавить стаканы ВСЕХ фьючерсов и
ГАРАНТИРОВАННО получишь тик в премаркет, не думая о работе других экспертов в терминале.
Т.е все новые котировки будут "идти" в отдельный советник.
Добавлено
который будет "заниматься" только синхронизацией, не мешая никому.
Пришла новая котировка и стакан изменился это разные события. При изменении стакана если добавлена (убрана) заявка выше ask или ниже bid, событие OnBookEvent() приходит, но это не новая котировка и в историю тиков она не попадает, следовательно и последнее известное время сервера не меняется.
Блин не знаю как еще объяснить, прикалываешься? ))