![MQL5 - Langage des stratégies de trading intégré au terminal client MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Vous manquez des opportunités de trading :
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Inscription
Se connecter
Vous acceptez la politique du site Web et les conditions d'utilisation
Si vous n'avez pas de compte, veuillez vous inscrire
Quelqu'un peut-il expliquer pourquoi ce code ne synchronise pas correctement l'heure ?
Après tout, le pré-marché reçoit une cotation "fraîche", avec la nouvelle heure du serveur (bourse).
Essayez ce que j'ai :
//| 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)],
"");
}
//+------------------------------------------------------------------+
Le temps fluctue en raison des délais de ping, de serveur et de terminal. Mais dans les -10 ; +10 ; millisecondes, ça fonctionne.
Dans le pré-marché, les tiques viennent aussi.
Essayez ce que j'ai :
Le temps fluctue en raison des délais de ping, de serveur et de terminal. Mais dans les -10 ; +10 ; millisecondes, ça fonctionne.
Dans le pré-marché, les tiques viennent aussi.
Merci, je vais essayer.
Ajouté
Ça a l'air pas mal, mais.
1. Si ce code est inséré dans un Expert Advisor de trading, comment synchroniser la correction entre les Experts Advisors, si
mon conseiller expert fonctionne sur plusieurs contrats à terme ?
2. Si vous mettez votre code dans un EA séparé, il n'y a aucune garantie que le OnTick vienne
dans ce symbole dans le premarket (cela peut ne pas venir) ?
3. Pourquoi OnTick() est-il meilleur que OnBookEvent() dans le premarket ?
Comment est-ce "correct"
que
Merci, je vais essayer.
Ajouté
Ça n'a pas l'air mauvais, mais
1. Si ce code est inséré dans un Expert Advisor de trading, comment synchroniser la correction entre les Experts Advisors, si
mon conseiller expert fonctionne sur plusieurs contrats à terme ?
2. Si vous mettez votre code dans un EA séparé, il n'y a aucune garantie que le OnTick vienne
dans ce symbole dans le premarket (ne viendra peut-être pas) ?
Il est préférable que le conseiller expert soit attaché à un graphique séparé, le plus liquide, car deux graphiques peuvent interférer l'un avec l'autre.
Quand il est préférable de supprimer la synchronisation, une synchronisation une fois par jour devrait suffire. L'horloge du courtier, de la bourse ou de l'ordinateur ne peut pas fonctionner ou être décalée à ce point.
Vous pouvez faire en sorte que le conseiller expert se supprime lui-même lorsqu'il se synchronise.
Il est préférable de placer le conseiller sur un graphique séparé plus liquide, deux graphiques peuvent interférer l'un avec l'autre.
Lorsqu'il est synchronisé, il est préférable de le supprimer. Une synchronisation une fois par jour devrait suffire. L'horloge du courtier, de la bourse ou de l'ordinateur ne peut pas tourner ou traîner autant.
Nous pouvons faire en sorte que le conseiller expert se supprime lui-même lorsqu'il se synchronise.
3. Почему OnTick() лучше, чем OnBookEvent() в премаркет?
Le plus "correct"
pas
comme je l'ai déjà expliqué, nous ne pouvons pas obtenir l'heure de changement du bâton, une telle fonctionnalité n'existe pas dans le terminal. Le changement de la coupe se produit non seulement lorsque Ask, Bid, Last sont modifiés, respectivement le moment de OnBookEvent() est inconnu.
vous ne pouvez obtenir que l'heure du tic.
OnTick() n'est pas meilleur que OnBookEvent(), il ne fonctionne tout simplement pas autrement.
D'un fil voisin :
Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading
Sanction : Tslab + plaza 2 vs MT 5
Alexey Kozitsyn, 2017.01.17 12:02
Vous ne comprenez pas. Je suis conscient de la structure des cotes, il n'y a pas de plaintes à ce sujet. Le problème est qu'en cas de souscription à des événements de mise à jour, il est impossible d'obtenir l'heure d'arrivée de cet événement, par conséquent si je reçois des ticks et que je veux ensuite connaître l'état de la tasse - je ne peux pas le faire, car il n'y a pas d'heure d'arrivée de la tasse ! La synchronisation est impossible ! De même avec d'autres indicateurs boursiers que j'ai cités dans le post précédent.
Et ma question était de savoir quand l'heure d'arrivée de la coupe + d'autres indicateurs boursiers comme l'OI seront ajoutés.
Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading
Sanction : Tslab + plaza 2 vs MT 5
Renat Fatkhullin, 2017.01.17 14:01
Réfléchissons.Je l'ai déjà expliqué, nous ne pouvons pas obtenir l'heure de changement de gobelet, cette fonctionnalité n'existe pas dans le terminal. Le changement de la coupe ne se produit pas seulement quand Ask, Bid, Last sont changés, respectivement le moment de OnBookEvent() est inconnu.
vous ne pouvez obtenir que l'heure du tic.
OnTick() n'est pas meilleur que OnBookEvent(), vous ne pouvez tout simplement pas faire autrement.
Sergei !
Regardez. Une nouvelle cotation est arrivée et le marché a changé, par conséquent, l'événement OnBookEvent() doit être reçu,
que nous utilisons simplement comme un EVENEMENT.
Ensuite, la façon dont vous obtenez les informations sur le tick parif( !SymbolInfoTick(_Symbol,tick)) ne fait aucune différence.{Print("errorSymbolInfoTick",GetLastError()) ;return; }
ouif(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)
Mais il y a une énorme différence entre mon approche et la vôtre.
Dans mon cas, en utilisant l'EA sur un instrument illiquide (par exemple UUAH), vous pouvez ajouter des piles de TOUS les contrats à terme et de tous les contrats à terme.
il est GARANTI d'obtenir un tick dans le premarket, sans se soucier du travail des autres Expert Advisors dans le terminal.
En d'autres termes, toutes les nouvelles citations "iront" dans un EA séparé.
Ajouté par
L'objectif principal de cette EA est de "s'occuper" uniquement de la synchronisation, sans interférer avec le travail de quiconque.
//| 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;
}
}
//+------------------------------------------------------------------+
Seulement, aujourd'hui, après 10:00 (la synchronisation était en pré-marché)
L'heure locale différait de l'heure de la montre du marché de 7 secondes. :(
Sergei !
Regardez. Une nouvelle cotation est arrivée, le marché a changé, donc l'événement OnBookEvent() doit être reçu,
que nous utilisons simplement comme EVENT.
Ensuite, la façon dont vous obtenez les informations sur le tick parif( !SymbolInfoTick(_Symbol,tick)) ne fait aucune différence.{Print("errorSymbolInfoTick",GetLastError()) ;return; }
ouif(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)
Mais il y a une énorme différence entre mon approche et la vôtre.
Dans mon cas, en utilisant l'EA sur un instrument illiquide (par exemple UUAH), vous pouvez ajouter des piles de TOUS les contrats à terme et de tous les contrats à terme.
il est GARANTI d'obtenir un tick dans le premarket, sans se soucier du travail des autres Expert Advisors dans le terminal.
En d'autres termes, toutes les nouvelles citations seront "envoyées" vers un EA séparé.
Ajouté par
Il ne s'occupera que de la synchronisation et n'interférera pas avec le travail des autres.
Une nouvelle cotation est arrivée et la profondeur du marché a changé - ce sont des événements différents. Si une offre supérieure ou inférieure à la demande est ajoutée (supprimée), l'événement OnBookEvent() se produit, mais il ne s'agit pas d'une nouvelle cotation et elle n'est pas enregistrée dans l'historique des tics ; par conséquent, la dernière heure connue du serveur ne change pas.
Je ne sais pas comment l'expliquer autrement, vous plaisantez ? ))