Sincronizzare l'ora locale di Windows con il server MT5 - pagina 6

 
prostotrader:

Qualcuno può spiegare perché questo codice non sincronizza accuratamente il tempo?

Dopo tutto, il premercato riceve una quotazione "fresca", con il nuovo orario del server (scambio).

Prova quello che ho:

//+------------------------------------------------------------------+
//|                                                    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 &ltime)
  {
   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)],
           "");
  }
//+------------------------------------------------------------------+


Il tempo fluttua a causa del ping, dei ritardi del server e del terminale. Ma entro -10; +10; millisecondi funziona.

Nel premercato arrivano anche le zecche.

 
Sergey Chalyshev:

Prova quello che ho:



Il tempo fluttua a causa del ping, dei ritardi del server e del terminale. Ma entro -10; +10; millisecondi funziona.

Nel premercato arrivano anche le zecche.

Grazie, farò una prova.

Aggiunto

Non sembra male, ma.

1. Se questo codice è inserito in un Expert Advisor di trading, come sincronizzare la correzione tra gli Expert Advisor, se

il mio Expert Advisor funziona su diversi futures?

2. Se metti il tuo codice in un EA separato, non c'è garanzia che l'OnTick venga

in questo simbolo nel premercato (potrebbe non venire)?

3. Perché OnTick() è meglio di OnBookEvent() nel premarket?

Come è "corretto"

if(!SymbolInfoTick(_Symbol,tick)) { Print("error SymbolInfoTick",GetLastError()); return; }

che

if(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)
 
prostotrader:

Grazie, farò una prova.

Aggiunto

Non sembra male, ma

1. Se questo codice è inserito in un Expert Advisor di trading, come sincronizzare la correzione tra gli Expert Advisor, se

il mio Expert Advisor funziona su diversi futures?

2. Se metti il tuo codice in un EA separato, non c'è garanzia che l'OnTick venga

in questo simbolo nel premercato (potrebbe non venire)?

L'Expert Advisor dovrebbe essere meglio collegato ad un grafico separato, il più liquido, in due grafici possono interferire l'uno con l'altro.

Quando è meglio rimuovere la sincronizzazione, una volta al giorno la sincronizzazione dovrebbe essere sufficiente. L'orologio del broker, della borsa o del computer non può correre o ritardare così tanto.

Puoi fare in modo che l'Expert Advisor si cancelli da solo quando si sincronizza.

 
Sergey Chalyshev:

È meglio mettere il consulente su un grafico separato più liquido, due grafici possono interferire l'uno con l'altro.

Quando è sincronizzato è meglio rimuovere, una volta al giorno la sincronizzazione dovrebbe essere sufficiente. L'orologio del broker, della borsa o del computer non può correre o ritardare così tanto.

Possiamo fare in modo che l'Expert Advisor si cancelli da solo quando si sincronizza.

E la terza domanda?
 

3. Почему OnTick() лучше, чем OnBookEvent() в премаркет? 

Il più "corretto"

if(!SymbolInfoTick(_Symbol,tick)) {Print("errorSymbolInfoTick",GetLastError());return; }

non

if(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)

come ho già spiegato, non possiamo ottenere il tempo di cambio dello stick, tale funzionalità non esiste nel terminale. Il cambiamento della coppa avviene non solo quando Ask, Bid, Last sono cambiati, rispettivamente il tempo di OnBookEvent() è sconosciuto.

si può ottenere solo l'ora della spunta.

OnTick() non è meglio di OnBookEvent(), semplicemente non funziona in nessun altro modo.


 

Da un thread vicino:

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Sanzione: Tslab + plaza 2 vs MT 5

Alexey Kozitsyn, 2017.01.17 12:02

Non lo capisci. Sono consapevole della struttura delle zecche, non ci sono lamentele al riguardo. La lamentela è che in caso di sottoscrizione di eventi di aggiornamento, è impossibile ottenere l'ora di arrivo di questo evento, di conseguenza se ho ricevuto dei tick e poi voglio sapere lo stato della tazza - non posso farlo, poiché non c'è l'ora di arrivo della tazza! La sincronizzazione è impossibile! Allo stesso modo con altri indicatori azionari che ho citato nel post precedente.

E la mia domanda era quando sarà aggiunto il tempo di arrivo dell'evento della coppa + altri indicatori azionari come OI.


 
Sergey Chalyshev:

Ho già spiegato che non possiamo ottenere l'ora del cambio della tazza, non c'è questa funzionalità nel terminale. Il cambiamento della coppa non avviene solo quando Ask, Bid, Last sono cambiati, rispettivamente il tempo di OnBookEvent() è sconosciuto.

si può ottenere solo l'ora della spunta.

OnTick() non è meglio di OnBookEvent(), semplicemente non si può fare in altro modo.


Sergei!

Guarda. È arrivata una nuova quotazione e il mercato è cambiato, di conseguenza, l'evento OnBookEvent() dovrebbe essere ricevuto,

che usiamo semplicemente come un EVENTO.

Poi, non fa alcuna differenza come si ottengono informazioni sul tick attraversoif(!SymbolInfoTick(_Symbol,tick)){Print("errorSymbolInfoTick",GetLastError());return; }

ose(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)

Ma c'è un'enorme differenza tra il mio approccio e il tuo.

Nel mio caso, utilizzando EA su strumento illiquido (per esempio UUAH) è possibile aggiungere pile di TUTTI i futures e

è GARANTITO ottenere un tick nel premercato, senza preoccuparsi del lavoro di altri Expert Advisors nel terminale.

Cioè tutte le nuove citazioni "andranno" in un EA separato.

Aggiunto da

Lo scopo principale di questo EA è quello di "occuparsi" solo della sincronizzazione, non di interferire con il lavoro di qualcun altro.

 
//+------------------------------------------------------------------+
//|                                              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;
     }
  }
//+------------------------------------------------------------------+
 

Solo, oggi, dopo le 10:00 (la sincronizzazione era in pre-mercato)

l'ora locale differisce da quella del Market Watch di 7 secondi. :(

 
prostotrader:

Sergei!

Guarda. È arrivata una nuova quotazione, il mercato è cambiato, quindi l'evento OnBookEvent() deve essere ricevuto,

che usiamo semplicemente come EVENTO.

Poi, non fa alcuna differenza come si ottengono informazioni sul tick attraversoif(!SymbolInfoTick(_Symbol,tick)){Print("errorSymbolInfoTick",GetLastError());return; }

ose(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)

Ma c'è un'enorme differenza tra il mio approccio e il tuo.

Nel mio caso, utilizzando EA su strumento illiquido (per esempio UUAH) è possibile aggiungere pile di TUTTI i futures e

è GARANTITO ottenere un tick nel premercato, senza preoccuparsi del lavoro di altri Expert Advisors nel terminale.

Cioè tutte le nuove citazioni "andranno" in un EA separato.

Aggiunto da

Si "occuperà" solo della sincronizzazione e non interferirà con il lavoro di nessun altro.

È arrivata una nuova quotazione e la profondità del mercato è cambiata - questi sono eventi diversi. Se un'offerta superiore o inferiore alla domanda viene aggiunta (rimossa), l'evento OnBookEvent() si verifica, ma non è una nuova quotazione e non arriva alla cronologia dei tick e quindi l'ultimo orario noto del server non cambia.

Non so come altro spiegarlo, stai scherzando? ))