Eineinhalb Minuten Unterschied zwischen der Ortszeit und der neuen Tickerzeit. Was ist zu tun? - Seite 2

 
prostotrader:

Es gibt Quellcode mit Kommentaren.

Sind Sie zu faul, sich das anzuschauen? Oder gibt es etwas, das ich nicht verstehe?

Das habe ich. Ich habe die Idee auch ohne den Code verstanden. Ich verstehe nicht, warum Sie mir einen Rat geben:

Prostotrader:

Sie müssen die liquidesten Instrumente zu Market Watch hinzufügen.

Fügen Sie dann Schichten von diesen Instrumenten hinzu.

Und, wenn OnBookEvent() auslöst, kopieren Sie 1 Tick (letzte) wird es eine Zeit und sofort nehmen die lokale Zeit und vergleichen.

Inwiefern ist Ihre Methode besser?

 
pivomoe:

Ich habe es mir angesehen. Ich habe die Idee auch ohne den Code verstanden. Ich verstehe nicht, warum Sie mir einen Rat geben:

Warum ist Ihre Methode besser?

Weil es das Richtige ist!

Ich habe einen Fehler gemacht, nicht bei der Ortszeit, sondern bei der Serverzeit.

(1) Die Zecken kommen in Paketen zum Terminal.

2. Jedes nachfolgende Paket kann Zecken enthalten, die im vorherigen Paket nicht "gestapelt" waren, aber die gleiche Zeit wie das vorherige Paket haben.

3 OnBookEvent() wird bei jedem Tick (Preisänderung, Volumen) ausgelöst, d.h. bei jedem Tick. (Sie lösen einen Timer aus - schon schlimm).

4. Sie verwenden lokale Computerzeit, die überhaupt nicht benötigt wird!

 

Hier finden Sie alles, was Sie für den Handel benötigen (überprüfen Sie die Zeiten der Handelssitzungen)

//+------------------------------------------------------------------+
//|                                                         Time.mq5 |
//|                                                   Copyright 2019 |
//|                                                                  |
//+------------------------------------------------------------------+
int is_book;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  is_book = MarketBookAdd(Symbol());
  if(is_book == false) return(INIT_FAILED);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol()); 
}
//+------------------------------------------------------------------+
// Expert Book event function                                        |
//+------------------------------------------------------------------+  
void OnBookEvent(const string &symbol)
{
  if(symbol == Symbol())
  {
    if(CheckMarketTime() == true)
    {
     //Торговое время
     //Наш код
    }
  }
}
//+------------------------------------------------------------------+
//| Expert Check Market Time function                                |
//+------------------------------------------------------------------+
bool CheckMarketTime()
{
  MqlDateTime cur_time, sv_time;
  MqlTick ticks[];
  cur_time.year = 0;
  TimeTradeServer(cur_time); //Возвращает расчетное текущее время торгового сервера.
  if(cur_time.year > 0)
  {
    int result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
    if(result > 0)
    {
      if(TimeToStruct(ticks[0].time, sv_time) == true)
      {
        if(sv_time.day_of_year == cur_time.day_of_year)      //Проверка, что это сегодняшний тик
        {
          ulong tr_time = sv_time.hour * 3600 + sv_time.min * 60 + sv_time.sec;
          if(((tr_time >= 3600) && (tr_time < 50370)) ||   //10:00:00 - 13:59:30
             ((tr_time >= 50700) && (tr_time < 67470)) ||  //14:05:00 - 19:44:30 
             ((tr_time >= 68700) && (tr_time < 85770)))    //19:05:00 - 23:49:30
          {
            return(true);
          }
        }
      }
    }
  }   
  return(false);
} 

Hinzugefügt von

Wenn Sie eine Millisekundengenauigkeit benötigen, dann ist diese

double t_msc = double(ticks[0].time_msc - ulong(ticks[0].time) * 1000)/1000; //Получаем в секундах
double tr_time = sv_time.hour * 3600 + sv_time.min * 60 + sv_time.sec + t_msc;

Hinzugefügt

Aber all dies wird nicht zum gewünschten Ergebnis führen (die Grenzen der Handelszeit), weil

In einer Handelssitzung kann es keine Ticks geben, und die Zeit bleibt nicht stehen.

Angenommen, jemand hat seinen schwebenden Auftrag entfernt, der Ticker hat sich geändert,

es gibt ein Signal, aber es gibt eine "alte" Korrelation (die Zeit ist nicht die aktuelle Zeit).

Das Terminal sendet nicht die genaue Serverzeit.

 

Du verstehst mich nicht. Fangen wir ganz am Anfang an.

1) In Ihrem Programm rufen Sie TimeCurrent() auf und erhalten die Ankunftszeit des letzten Kurses für eines der ausgewählten Symbole in Market Watch.

Es soll 18:00:00 Uhr sein.

2) Mit dem nächsten Befehl erhalten Sie den Zeitpunkt des letzten SBER-Ticks.

Lass es sein 17:58:00

3) Es vergeht ein wenig Zeit und Sie fragen erneut den Zeitpunkt des letzten Ticks per SBER ab.

Lass es 17:59:00 sein


Beachten Sie die Frage: Finden Sie es in Ordnung, dass TimeCurrent() um 18:00:00 Uhr nichts von dem Tick mit der Zeit 17:59:00 weiß?

 
pivomoe:

Du verstehst mich nicht. Fangen wir ganz am Anfang an.

1) In Ihrem Programm rufen Sie TimeCurrent() auf und erhalten die Ankunftszeit des letzten Kurses für eines der ausgewählten Symbole in Market Watch.

Es soll 18:00:00 Uhr sein.

2) Mit dem nächsten Befehl erhalten Sie den Zeitpunkt des letzten SBER-Ticks.

Lass es sein 17:58:00

3) Es vergeht ein wenig Zeit und Sie fragen erneut den Zeitpunkt des letzten Ticks per SBER ab.

Lass es 17:59:00 sein


Achtung Frage: Glauben Sie, dass es OK ist, um 18:00:00 durch TimeCurrent() von einem Tick mit der Zeit 17:59:00 unbemerkt zu sein?

In dem von mir zitierten Code können Sie alle Ticks berücksichtigen (kein Problem)

Der letzte Code verwendet nicht TineCurrent() sondernTimeTradeServer() - diese Zeit wird nur benötigt

die Zecke mit einer Genauigkeit von einem Tag zu überprüfen und das war's!

Fangen wir von vorne an.

Was wollen Sie im Allgemeinen tun, um das herauszufinden?

Warum haben Sie angefangen, die Zeckenzeit mit der Ortszeit zu vergleichen?

Was ist der ursprüngliche Zweck?

 

Ich werde Ihnen nun zeigen, wie dieses Problem in der Praxis aussieht. Ich habe den Expert Advisor komplett umgestaltet. Ich habe es möglich gemacht, neue Ticks sowohl in OnTimer als auch in OnBookEvent zu erfassen.

Es gibt 45 Symbole in Market Watch. Die meisten von ihnen sind nicht flüssig.

Hier ist das Ergebnis des Abfangens neuer Ticks in OnBookEvent:

РЕКОРДная  Разница между временем последенго тика по ВСЕМ символам Минус только, что полученный новый тик по символу 494013 милесекундa.

CR      0       18:51:47.334    ProverkaAktyalnostiTikov (ALRS,H1)       Получен НОВЫЙ тик по символу                     SNGR-3.19 time_msc= 2019.03.18 18:41:47.988

HN      0       18:51:47.335    ProverkaAktyalnostiTikov (ALRS,H1)       ХОТЯ до этого был получeн тик                        ARMD time_msc 2019.03.18 18:50:02.001

D.h. ein neuer Tick wurde um 18:50 auf TimeCurrent für das SymbolSNGR-3.19 mit einer Zeit von 18:41 gefangen.


Außerdem gibt es derzeit Messungen der lokalen Computerzeit:


1) Erhalten eines neuen Ticks, d.h. zum Zeitpunkt des letzten Aufrufs von CopyTick (oder SymbolInfo, je nach Einstellungen).

2) Der Zeitpunkt des letzten Anrufs.

18:51:47.335    ProverkaAktyalnostiTikov (ALRS,H1)       Локальное время получения нового тика по символу.                      2019.03.18 18:51:47.334

18:51:47.335    ProverkaAktyalnostiTikov (ALRS,H1)       Предпоследние Локальное время попытки получить новый тик по символу    2019.03.18 18:41:47.204


In diesem Fall trat das Problem also auf, weil die Funktion get new einfach 10 Minuten lang nicht aufgerufen wurde.... Das liegt daran, dass das OnBookEvent-Ereignis fürSNGR-3.19 10 Minuten lang nicht erzeugt wurde.

Vielleicht hat das Terminal es in die Ereigniswarteschlange gestellt und es ist irgendwie aus dieser Warteschlange verschwunden. Bei OnTimer gibt es keine solchen Fehler. Ja, es kann einen Tick mit 20 Sekunden Verzögerung geben.


 
pivomoe:


Was ist Ihr ursprüngliches Ziel?

Warum müssen Sie die Abschlagzeiten mit der Ortszeit vergleichen?

 
prostotrader:

Was ist Ihr ursprüngliches Ziel?

Warum müssen Sie die Tickzeiten mit der Ortszeit vergleichen?

Ich möchte die maximale Verzögerung zwischen dem Auftreten des Ticks auf dem Server und seinem Eintreffen im Terminal wissen. Und ich möchte wissen, wie ich diese Zeit verkürzen kann.

Dieses Wissen kann ich beim Schreiben meines eigenen Testers nutzen. Sie können die Entwickler sogar bitten, die Verzögerung zu verlängern.

TimeCurrent() - die Zeit des letzten Ticks eines Symbols ist kleiner als die Verzögerungszeit, so dass sie verwendet werden kann. Die Verwendung der Ortszeit in der ersten Version war keine gute Idee.

 
pivomoe:

Ich möchte die maximale Verzögerung zwischen dem Auftreten eines Ticks auf dem Server und dem Eintreffen auf dem Terminal wissen. Und wie man diese Zeit minimiert.

Dieses Wissen kann ich nutzen, wenn ich mein eigenes Testprogramm schreibe. Und vielleicht gelingt es mir sogar, die Entwickler mit längeren Verzögerungen zu verblüffen.

Ich verstehe. Fahren Sie fort... Ohne mich.

Und für die übrigen Mitglieder des Forums

//+------------------------------------------------------------------+
//|                                                         Time.mq5 |
//|                                                   Copyright 2019 |
//|                                                                  |
//+------------------------------------------------------------------+
enum FRESH_TICK
{
  UNKNOWN_TICK,
  NEW_TICK,
  CUR_TICK
};
//
int is_book;
ulong last_tick_time; //Время последнего тика
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  last_tick_time = 0;
  is_book = MarketBookAdd(Symbol());
  if(is_book == false) return(INIT_FAILED);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol()); 
}
//+------------------------------------------------------------------+
// Expert Book event function                                        |
//+------------------------------------------------------------------+  
void OnBookEvent(const string &symbol)
{
  if(symbol == Symbol())
  {
    MqlTick a_ticks[];
    int result = CopyTicks(symbol, a_ticks, COPY_TICKS_ALL, 0, 1);
    if(result > 0)
    {
      FRESH_TICK tick_state = CheckTickTime(a_ticks[0]);
      switch(tick_state)
      {
       case UNKNOWN_TICK:; //Тик не определен
       break;
       case NEW_TICK:;     //Торговое время, можно отсылать ордера;
       break;
       case CUR_TICK:;     //По усмотрению разработчика;
       break;
      }
    }  
  }
}
//+------------------------------------------------------------------+
//| Expert Check Market Time function                                |
//+------------------------------------------------------------------+
FRESH_TICK CheckTickTime(MqlTick &a_tick)
{
  MqlDateTime cur_time, tick_time;
  cur_time.year = 0;
  TimeTradeServer(cur_time); //Возвращает расчетное текущее время торгового сервера.
  if(cur_time.year > 0)
  {
    if(TimeToStruct(a_tick.time, tick_time) == true)
    {
      if(tick_time.day_of_year == cur_time.day_of_year)      //Проверка, что это сегодняшний тик
      {
        double t_msc = double(a_tick.time_msc - ulong(a_tick.time) * 1000)/1000;
        double tr_time = double(tick_time.hour * 3600 + tick_time.min * 60 + tick_time.sec) + t_msc;
        if(((tr_time >= 36000) && (tr_time < 50370)) ||   //10:00:00 - 13:59:30
           ((tr_time >= 50700) && (tr_time < 67470)) ||   //14:05:00 - 19:44:30 
           ((tr_time >= 68700) && (tr_time < 85770)))     //19:05:00 - 23:49:30
        {
          if(ulong(a_tick.time_msc) > last_tick_time)
          {
            last_tick_time = ulong(a_tick.time_msc);
            return(NEW_TICK);
          } else return(CUR_TICK);  
        }
      }
    }
  }   
  return(UNKNOWN_TICK);
} 
      
 
pivomoe:

Achtung Frage: Halten Sie es für normal, dass TimeCurrent() bei einer Uhrzeit von 17:59:00 einen Tick um 18:00:00 Uhr nicht bemerkt?

Ich denke, die Frage ist überflüssig. Die Ticksequenz muss mindestens die folgenden Kriterien erfüllen:

1. Sie muss sequentiell sein, d. h. der Zeitpunkt jedes nachfolgenden Ticks ist größer als der Zeitpunkt des vorherigen Ticks;

2. Aktualität. D.h. der Zeitpunkt des letzten eintreffenden Ticks liegt so nah wie möglich am aktuellen Zeitpunkt;

Es scheint, dass das Problem beim zweiten Punkt liegt.

Die Argumentation zu Punkt 2 lautet wie folgt: Ich möchte, dass die Zeit von der Tick-Erzeugung auf dem Server bis zum Erhalt des Ticks (Lag) minimal ist, damit ich ihn schneller als andere verarbeiten und eine Handelsentscheidung treffen kann. Aber wenn die Verzögerung für alle Bieter gleich ist, dann gibt es kein Problem (soweit ich das verstanden habe). Das heißt, der Server des Brokers hat das Problem, aber alle sind gleichberechtigt. Wenn jemand die Information über die Zecke um 17:59:01 Uhr erhalten hat, ich aber nicht einmal um 18:00 Uhr - das ist das große Problem.

Und hier ist die Frage. Was ist das Problem (und gibt es eines)? Im Server des Brokers, der den Tick (für alle) lange Zeit nicht freigibt, oder im MT5, der ihn lange Zeit nicht empfängt.