将Windows本地时间与MT5服务器同步 - 页 6

 
prostotrader:

谁能解释一下为什么这段代码不能准确地同步时间?

毕竟,市场前收到一个 "新 "的报价,有新的服务器(交易所)时间。

试试我有什么。

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


时间会因ping、服务器和终端的延迟而波动。但在-10;+10;毫秒内,它是有效的。

在市场前的蜱虫也来了。

 
Sergey Chalyshev:

试试我有什么。



时间会因ping、服务器和终端的延迟而波动。但在-10;+10;毫秒内,它是有效的。

在盘前,蜱虫也来了。

谢谢,我会试一试的。

添加

看起来还不错,但是。

1.如果这段代码被插入到一个交易专家顾问中,如何在专家顾问之间同步修正,如果

我的 "专家顾问 "能在几种期货上工作吗?

2.如果你把你的代码放在一个单独的EA中,不能保证OnTick会来

进入这个符号的前市(可能不会来)?

3.为什么在市场前期,OnTick()比OnBookEvent()更好?

它是如何 "正确"

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

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

谢谢,我会试一试的。

添加

它看起来并不坏,但

1.如果这段代码被插入到一个交易专家顾问中,如何在专家顾问之间同步修正,如果

我的 "专家顾问 "能在几种期货上工作吗?

2.如果你把你的代码放在一个单独的EA中,不能保证OnTick会来

进入这个符号的前期市场(可能不会来)?

专家顾问最好附在一个单独的图表上,即流动性最强的图表上,在两个图表上可能会相互干扰。

什么时候同步比较好去掉,一天同步一次应该就够了。经纪人、交易所或计算机的时钟不能运行或滞后那么多。

你可以让专家顾问在同步时自我删除。

 
Sergey Chalyshev:

最好把顾问放在一个单独的最具流动性的图表上,两个图表可能会相互干扰。

当它同步的时候,最好把它删除,每天同步一次应该就够了。经纪人、证券交易所或计算机的时钟不能运行或滞后那么多。

我们可以让专家顾问在同步时自我删除。

第三个问题呢?
 

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

更加 "正确"

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

不是

如果(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)

正如我已经解释过的,我们无法获得 棍子的变化时间,终端中不存在这样的功能。杯子的变化不仅发生在Ask、Bid、Last被改变的时候,而且分别发生在OnBookEvent()的时间未知。

你只能得到打钩的时间。

OnTick()并不比OnBookEvent()好,它只是没有任何其他的工作方式。


 

来自一个邻近的主题。

关于交易、自动交易系统和交易策略测试的论坛

制裁:Tslab + plaza 2 vs MT 5

Alexey Kozitsyn, 2017.01.17 12:02

你不明白。我知道蜱虫结构,对它没有任何抱怨。抱怨的是,在订阅更新事件的情况下,不可能得到这个事件的到达时间,因此,如果我收到了蜱虫,然后想知道杯子的状态--我不能这样做,因为没有杯子的到达时间!同步是不可能的!与我在上一篇文章中引用的其他股票指标类似。

我的问题是,什么时候能增加杯子的事件到达时间和其他股票指标,如OI。


 
Sergey Chalyshev:

我已经解释过了,我们无法得到杯子的更换时间,终端中没有这样的功能。当Ask、Bid、Last发生变化时,杯子的变化并没有发生,分别是OnBookEvent()的时间未知。

你只能得到打钩的时间。

OnTick()并不比OnBookEvent()好,只是你不能用其他方式。


谢尔盖!

看。一个新的报价已经到来,市场已经发生变化,因此,应该收到OnBookEvent()事件。

我们只是把它作为一个EVENT。

然后,你如何通过if(!SymbolInfoTick(_Symbol,tick)) 获得tick的信息并没有任何区别。{Print("errorSymbolInfoTick",GetLastError();return; }

或者如果(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)

但我的方法和你的方法有很大的不同。

在我的例子中,在非流动性工具上使用EA(例如UUAH),你可以添加所有期货的堆栈和

它可以保证在市场前期获得一个刻度,而不必担心终端中其他专家顾问的工作。

也就是说,所有新的报价将 "进入 "一个单独的EA。

由以下人员添加

该EA的主要目的是只 "处理 "同步问题,不干扰其他人的工作。

 
//+------------------------------------------------------------------+
//|                                              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秒。:(

 
prostotrader:

谢尔盖!

看。 一个新的报价来了,市场发生了变化,因此必须收到OnBookEvent()事件。

我们简单地将其作为EVENT。

然后,你如何通过if(!SymbolInfoTick(_Symbol,tick)) 获得tick的信息并没有任何区别。{Print("errorSymbolInfoTick",GetLastError();return; }

或者如果(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)

但我的方法和你的方法有很大的不同。

在我的例子中,在非流动性工具上使用EA(例如UUAH),你可以添加所有期货的堆栈和

它可以保证在市场前期获得一个刻度,而不必担心终端中其他专家顾问的工作。

也就是说,所有新的报价将 "进入 "一个单独的EA。

由以下人员添加

它将只 "处理 "同步问题,不会干扰其他任何人的工作。

一个新的报价已经到来,市场深度已经改变--这些都是不同的事件。如果一个高于或低于要价的出价或要价被添加(删除),OnBookEvent()事件就会发生,但这不是一个新的报价,它不会进入tick历史,因此最后已知的服务器时间 不会改变。

我不知道还能怎么解释,你在开玩笑吗?))

原因: