Sincronizar la hora local de Windows con el servidor MT5 - página 6

 
prostotrader:

¿Puede alguien explicar por qué este código no sincroniza la hora con precisión?

Al fin y al cabo, el premercado recibe una cotización "fresca", con la nueva hora del servidor (bolsa).

Prueba lo que tengo:

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


El tiempo fluctúa debido a los retrasos del ping, del servidor y del terminal. Pero dentro de -10; +10; milisegundos funciona.

En el premercado también vienen las garrapatas.

 
Sergey Chalyshev:

Prueba lo que tengo:



El tiempo fluctúa debido a los retrasos del ping, del servidor y del terminal. Pero dentro de -10; +10; milisegundos funciona.

En el premercado también vienen las garrapatas.

Gracias, lo intentaré.

Añadido

No se ve mal, pero.

1. Si este código se inserta en un Asesor Experto de comercio, cómo sincronizar la corrección entre Asesores Expertos, si

¿mi Asesor Experto funciona con varios futuros?

2. Si pones tu código en un EA separado, no hay garantía de que el OnTick venga

en este símbolo en el premercado (puede que no llegue)?

3. ¿Por qué es mejor OnTick() que OnBookEvent() en el premercado?

¿Cómo es "correcto"?

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

que

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

Gracias, lo intentaré.

Añadido

No se ve mal, pero

1. Si este código se inserta en un Asesor Experto de comercio, cómo sincronizar la corrección entre Asesores Expertos, si

¿mi Asesor Experto funciona con varios futuros?

2. Si pones tu código en un EA separado, no hay garantía de que el OnTick venga

en este símbolo en el premercado (puede que no llegue)?

Es mejor que el Asesor Experto se adjunte a un gráfico separado, el más líquido, en dos gráficos pueden interferir entre sí.

Cuando es mejor eliminar la sincronización, una vez al día debería ser suficiente. El reloj del broker, de la bolsa o del ordenador no puede correr o retrasarse tanto.

Puede hacer que el Asesor Experto se borre a sí mismo cuando se sincronice.

 
Sergey Chalyshev:

Es mejor poner el asesor en un gráfico separado más líquido, dos gráficos pueden interferir entre sí.

Cuando se sincroniza es mejor eliminar, una vez al día la sincronización debería ser suficiente. El reloj del broker, de la bolsa o del ordenador no puede correr o retrasarse tanto.

Podemos hacer que el Asesor Experto se borre a sí mismo cuando se sincronice.

¿Y la tercera pregunta?
 

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

Lo más "correcto"

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

no

if(CopyTicks(símbolo,curr_tick,COPY_TICKS_INFO,0,1)==1)

como ya he explicado, no podemos obtener el tiempo de cambio del palo, tal funcionalidad no existe en el terminal. El cambio de la copa se produce no sólo cuando Ask, Bid, Last se cambian, respectivamente el tiempo de OnBookEvent() es desconocido.

sólo se puede obtener la hora de la garrapata.

OnTick() no es mejor que OnBookEvent(), simplemente no funciona de otra manera.


 

De un hilo vecino:

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Sanción: Tslab + plaza 2 vs MT 5

Alexey Kozitsyn, 2017.01.17 12:02

No lo entiendes. Soy consciente de la estructura de las garrapatas, no hay quejas al respecto. ¡La queja es que en caso de suscribirse a eventos de actualización, es imposible obtener la hora de llegada de este evento, en consecuencia, si recibí ticks y luego quiero saber el estado de la copa - no puedo hacerlo, ya que no hay hora de llegada de la copa! La sincronización es imposible. Lo mismo ocurre con otros indicadores bursátiles que he citado en el post anterior.

Y mi pregunta era cuándo se añadirá la hora de llegada del evento de la copa + otros indicadores bursátiles como el OI.


 
Sergey Chalyshev:

Ya lo he explicado, no podemos obtener la hora de cambio de la copa, no existe esa funcionalidad en el terminal. El cambio de la copa no ocurre sólo cuando se cambian Ask, Bid, Last, respectivamente el tiempo de OnBookEvent() es desconocido.

sólo se puede obtener la hora de la garrapata.

OnTick() no es mejor que OnBookEvent(), simplemente no se puede hacer de otra manera.


¡Sergei!

Mira. Ha llegado una nueva cotización y el mercado ha cambiado, en consecuencia, se debe recibir el evento OnBookEvent(),

que simplemente utilizamos como un EVENTO.

Entonces, no hace ninguna diferencia cómo se obtiene la información sobre el tick a través deif(!SymbolInfoTick(_Symbol,tick)){Print("errorSymbolInfoTick",GetLastError());return; }

oif(CopyTicks(símbolo,curr_tick,COPY_TICKS_INFO,0,1)==1)

Pero hay una gran diferencia entre mi enfoque y el tuyo.

En mi caso, utilizando el EA en un instrumento sin liquidez (por ejemplo UUAH) puedes añadir pilas de TODOS los futuros y

está GARANTIZADA la obtención de un tick en el premercado, sin preocuparse del trabajo de otros Asesores Expertos en el terminal.

Es decir, todas las nuevas cotizaciones "irán" a un EA separado.

Añadido por

El objetivo principal de este EA es "ocuparse" únicamente de la sincronización, sin interferir en el trabajo de los demás.

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

Sólo, hoy, después de las 10:00 (la sincronización fue en el pre-mercado)

Lahora local difiere de la hora del reloj de mercado en 7 segundos. :(

 
prostotrader:

¡Sergei!

Mira. Ha llegado una nueva cotización, el mercado ha cambiado, por lo que hay que recibir el evento OnBookEvent(),

que utilizamos simplemente como EVENT.

Entonces, no hace ninguna diferencia cómo se obtiene la información sobre el tick a través deif(!SymbolInfoTick(_Symbol,tick)){Print("errorSymbolInfoTick",GetLastError());return; }

oif(CopyTicks(símbolo,curr_tick,COPY_TICKS_INFO,0,1)==1)

Pero hay una gran diferencia entre mi enfoque y el tuyo.

En mi caso, utilizando el EA en un instrumento sin liquidez (por ejemplo UUAH) puedes añadir pilas de TODOS los futuros y

está GARANTIZADA la obtención de un tick en el premercado, sin preocuparse del trabajo de otros Asesores Expertos en el terminal.

Es decir, todas las nuevas cotizaciones "irán" a un EA separado.

Añadido por

Sólo se "ocupará" de la sincronización y no interferirá en el trabajo de los demás.

Una nueva cotización ha llegado y la profundidad del mercado ha cambiado: son acontecimientos diferentes. Si se añade (elimina) una oferta o un precio mayor o menor que el ask, se produce el evento OnBookEvent() pero no es una nueva cotización y no llega al historial de ticks y por tanto no cambia la última hora conocida del servidor.

No sé de qué otra manera explicarlo, ¿estás bromeando? ))

Razón de la queja: