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.このコードがトレーディングExpert Advisorに挿入されている場合、Expert Advisor間で補正を同期させる方法、もし

私のExpert Advisorは複数の先物で動作するのですか?

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.このコードがトレーディングExpert Advisorに挿入されている場合、Expert Advisor間で補正を同期させる方法、もし

私のExpert Advisorは複数の先物で動作するのですか?

2.別のEAにコードを入れた場合、OnTickが来る保証はない。

をプレマーケットでこのシンボルに(来ないかも)?

Expert Advisor は、2 つのチャートが互いに干渉し合う可能性があるため、最も流動的な別のチャートに取り付 けるのがよいでしょう。

同期を外した方が良い場合、1日1回の同期で十分です。ブローカーや取引所、コンピュータの時計がそんなに動いたり遅れたりすることはありえない。

Expert Advisor が同期する際に、自分自身を削除するようにすることができます。

 
Sergey Chalyshev:

アドバイザーは別の最も流動的なチャートに置く方が良い、2つのチャートは互いに干渉する可能性があります。

同期しているときは削除したほうがよく、1日1回の同期で十分です。ブローカー、証券取引所、コンピュータの時計は、そんなに走ったり遅れたりすることはできません。

Expert Advisor が同期する際に、自分自身を削除するようにすることができます。

そして3つ目の質問は?
 

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

より "正しい "もの

if(!SymbolInfoTick(_Symbol,tick)){Print("エラーSymbolInfoTick",GetLastError());return; }.

ノット

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

既に説明したように、スティックの交換時刻を取得 することはできません。このような機能はターミナルに存在しません。カップの変更はAsk, Bid, Lastが変更されたときだけでなく、それぞれOnBookEvent()の時刻が不明なときにも発生する。

は、刻みの時間しか取得できません。

OnTick()はOnBookEvent()よりも優れているわけではなく、それ以外の方法で動作しないだけです。


 

隣のスレッドから。

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

サンクション:ツララ+プラザ2 vs MT5

アレクセイ・コジツィン さん 2017.01.17 12:02

わかってないなぁ。ティック構造については、不満はありません。不満なのは、更新イベントを受信した場合、このイベントの到着時刻を取得できないことです。したがって、ティックを受信して、カップの状態を知りたい場合、カップの到着時刻がないため、これを行うことはできません同期がとれない!?前回の記事で引用した他の株価指標も同様です。

そして、私の質問は、カップのイベント到着時間+OIのような他の株式指標はいつ追加されるのかということでした。


 
Sergey Chalyshev:

すでに説明したように、カップの交換時刻を取得することはできません、端末にはそのような機能はありません。Ask、Bid、Lastを変更したときだけカップの変更が行われるのではなく、それぞれOnBookEvent()の時刻が不明である。

は、刻みの時間しか取得できません。

OnTick()はOnBookEvent()に勝るとも劣らない、他に方法がないだけです。


セルゲイ!

見てください。新しい相場が来て、相場が変わったので、OnBookEvent()イベントを受信する必要があります。

を、単にEVENTとして使用します。

それから、ティックに関する情報をどのように取得するかは、if(!SymbolInfoTick(_Symbol,tick)) を通しても変わりません。{Print("エラーSymbolInfoTick",GetLastError());return; }.

またはif(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)

しかし、私とあなたのアプローチには大きな違いがあります。

私の場合、流動性の低い商品(例えばUUAH)でEAを使用すると、すべての先物のスタックを追加して

ターミナル内の他のExpert Advisorの動作を気にすることなく、プレマーケットでティックを取得することが保証されています。

すなわち、すべての新しい見積もりは、別の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時過ぎに(同期は市場前)

現地時刻と Market Watchの時刻が7秒違っていた。:(

 
prostotrader:

セルゲイ!

見てください。 新しい相場が来た、市場が変わった、だからOnBookEvent()イベントを受信しなければならない。

を、単にEVENTとして使用します。

それから、ティックに関する情報をどのように取得するかは、if(!SymbolInfoTick(_Symbol,tick)) を通しても変わりません。{Print("エラーSymbolInfoTick",GetLastError());return; }.

またはif(CopyTicks(symbol,curr_tick,COPY_TICKS_INFO,0,1)==1)

しかし、私とあなたのアプローチには大きな違いがあります。

私の場合、流動性の低い商品(例えばUUAH)でEAを使用すると、すべての先物のスタックを追加して

ターミナル内の他のExpert Advisorの動作を気にすることなく、プレマーケットでティックを取得することが保証されています。

すなわち、すべての新しい引用は、別のEAに「行く」。

によって追加されました。

同期だけを "扱う "ので、他の人の作業を邪魔することはありません。

新しい相場が来た、市場の深さが変わった、これらは別の出来事です。アスクより高いまたは低いビッドまたはオファーが追加(削除)されると、OnBookEvent()イベントが発生しますが、それは新しい気配値ではなく、ティック履歴には残らないので、最終的に知られているサーバー時刻は 変更されません。

他にどう説明したらいいのかわからない、冗談でしょう?))