Tiki en temps réel - page 4

 
Vladimir Mikhailov:

Un petit résumé des expériences avec une analyse des tics.

1. le gestionnaire OnTick saute un nombre important de ticks.
Par conséquent, si l'on veut analyser la bande des transactions à travers le tick entrant, cela n'a aucun sens.
Avec cette approche, les résultats de l'algorithme dans le testeur et les résultats réels du trading seront différents.

Comme alternative, vous pouvez analyser la bande de transactions pour une période sélectionnée ou une certaine quantité de dernières transactions en obtenant les ticks de l'historique à l'aide des fonctions CopyTicks() ou CopyTicksRange().
Dans ce cas, les résultats du test de l'algorithme dans le testeur et les résultats du commerce réel sont les mêmes.
Les inconvénients sont une performance moindre de l'algorithme.

Oui, le conseiller expert peut manquer des ticks. Par conséquent, c'est soit l'indicateur, soit CopyTicks.

Et la dégradation des performances due à quoi ? Copiez uniquement le segment requis (qui est apparu depuis la dernière extraction de données réussie).

 
Andrey Khatimlianskii:

Pourquoi les collecter "en temps réel" si CopyTicks est utilisé de toute façon ?

Vous pouvez copier les tics à la bonne profondeur à tout moment.

Andrew, lis le titre du sujet

Ajouté

Vous ne pouvez pas l'amener à la bonne profondeur avec CopyTicks(), il n'y a que 2000 ticks !

 
prostotrader:

Andrei, lis le titre du sujet

Qu'en est-il du fait que la tâche est initialement mal définie ?

L'analyse des ticks en temps réel est possible, mais il est nécessaire d'utiliser un indicateur ou CopyTicks pour éviter les écarts.


prostotrader:

Vous ne pouvez pas obtenir la profondeur requise avec CopyTicks(), mais seulement 2000 ticks !

Cette limitation n'existe pas, voir l'exemple dans la documentation:

Пример вывода
Si-12.16: received 11048387  ticks in 4937 ms
Last tick time = 2016.09.26 18:32:59.775 
First tick time = 2015.06.18 09:45:01.000 
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyTicks
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyTicks
  • www.mql5.com
[in]  Количество запрашиваемых тиков. Если параметры from и count не указаны, то в массив ticks_array[] будут записаны все доступные последние тики, но не более 2000. Первый вызов CopyTicks() инициирует синхронизацию базы тиков, хранящихся на жёстком диске по данному символу. Если тиков в локальной базе не хватает, то недостающие тики...
 
Andrey Khatimlianskii:

Qu'en est-il du fait que la tâche est initialement mal définie ?

L'analyse des ticks en temps réel est possible, mais vous devez utiliser un indicateur ou CopyTicks pour vous assurer qu'il n'y a pas d'omissions.


Cette limitation n'existe pas, voir l'exemple dans la documentation:

1. Pas nécessairement un indicateur !

Si vous voulez dire l'aide, qui dit

Dans les conseillers experts et les scripts, la fonction CopyTicks() peut attendre jusqu'à 45 secondes.....

Si vous lisez jusqu'à la fin, il est dit

Vitesse de sortie: le terminal stocke pour chaque caractère 4096 derniers ticks dans le cache pour un accès rapide (65536 ticks pour les caractères avec la pile en cours ), les requêtes sur ces données sont les plus rapides.

L'événement OnBookEvent() est déclenché lorsqu'un nouveau paquet de ticks arrive au terminal, donc

il est possible de collecter des ticks à partir du conseiller expert. Prenez un exemple et vérifiez-le.

//+------------------------------------------------------------------+
//|                                                   Ticks_test.mq5 |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
bool is_book;
MqlTick ticks[];
ulong last_time, mem_time;
bool is_first;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
    is_first = false;
    is_book = MarketBookAdd(Symbol());
    int result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
    if(result > 0)
    {
      last_time = ticks[0].time_msc;
      is_first = true;
    }
    else
    {
      Alert("No start time!");
      return(INIT_FAILED);
    }   
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
    if(is_book == true) MarketBookRelease(Symbol());
   
  }
void PrintResult(const int cnt)
{
  if(cnt > 0)
  {
    for(int i= 0; i<cnt; i++)
    {
      if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) Print("Tick is ", "TICK_FLAG_ASK"); else
      if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) Print("Tick is ", "TICK_FLAG_BID"); else
      if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) Print("Tick is ", "TICK_FLAG_BUY"); else
      if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) Print("Tick is ", "TICK_FLAG_LAST"); else
      if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) Print("Tick is ", "TICK_FLAG_SELL"); else
      if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) Print("Tick is ", "TICK_FLAG_VOLUME"); else
      Print("Unknown flag is ", ticks[i].flags);
    }
  }
}  
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
    if(Symbol() == symbol)
    {
      int result;
      if(is_first == true)
      {
        Print("First packet of ticks:");
        result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
        if(result > 0)
       {
         PrintResult(result);
         is_first = false;
         mem_time = last_time;
         last_time = ticks[0].time_msc + 1;
       } 
      }
      else
      {
        result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, mem_time, 0);
        if(result > 0)
        {
          for(int i= 0; i<result; i++)
          {
            if(ticks[i].time_msc == mem_time)
            {
              Print("Tick with old time:");
              if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) Print("Tick is ", "TICK_FLAG_ASK"); else
              if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) Print("Tick is ", "TICK_FLAG_BID"); else
              if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) Print("Tick is ", "TICK_FLAG_BUY"); else
              if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) Print("Tick is ", "TICK_FLAG_LAST"); else
              if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) Print("Tick is ", "TICK_FLAG_SELL"); else
              if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) Print("Tick is ", "TICK_FLAG_VOLUME"); else
              Print("Unknown flag is ", ticks[i].flags);
            }
          }
        }
        result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
        if(result > 0)
        {
          Print("Ticks with new time:");
          PrintResult(result);
          mem_time = last_time;
          last_time = ticks[0].time_msc + 1;
        }
      }
    }
 }
//+------------------------------------------------------------------+


2. Il existe une telle limitation, vérifiez-la vous-même(CopyTicksRange() n'a pas de limitation).


 
prostotrader:

1. Pas nécessairement un indicateur !

L'événement OnBookEvent() est déclenché lorsqu'un nouveau paquet de ticks arrive dans le terminal, donc

il est possible de collecter des ticks à partir du conseiller expert. Prenez un exemple et vérifiez-le.

OnBookEvent ne garantit pas que les ticks ne seront pas manqués. S'il y a des calculs lourds à cet endroit, il y aura le même saut que dans OnTick.

Et il importe peu de savoir d'où copier la profondeur de ticks nécessaire via CopyTicks.


prostotrader:

2. Il existe une telle limitation, vérifiez-la vous-même

Elle n'existe que pour les paramètres 0, 0, ce qui est explicitement mentionné dans l'aide :

Если параметры from и count не указаны, то в массив ticks_array[] будут записаны все доступные последние тики, но не более 2000.
 
Andrey Khatimlianskii:

OnBookEvent ne garantit pas que les ticks ne seront pas manqués.

Je répète

OnBookEvent() donne précisément cette garantie qu'un nouveau lot de tics est arrivé !

De la référence :

Taux d'émission: Le terminal stocke pour chaque caractère 4096 derniers ticks dans le cache à accès rapide (pour les caractèresavec la pile en marche, 65536 ticks), les requêtes sur ces données sontles plus rapides.

Fin de la citation----

Si OnBookEvent n'était pas déclenché, tout le trading (échange) dans MT5 pourrait être jeté à la poubelle !

Un nouveau paquet de ticks est arrivé - 100% a déclenché OnBookEvent, et la CopyTicks() montre combien de ticks sont arrivés,

les données sont déjà stockées dans le cache et c'est l'accès le plus rapide!

C'est pourquoi le collecteur de ticks peut être implémenté en temps réel dans les indicateurs et les EA(lorsque le marché fonctionne).

Ajouté par

Prenez le code ci-dessus et vérifiez-le, puis discutez...

 

Le code du collecteur de tiques est correct, mais il y a quelques erreurs d'implémentation.

et le poster plus tard.

Ajouté

Collecte de tous les ticks en temps réel depuis l'Expert Advisor

Veuillez utiliser

//+------------------------------------------------------------------+
//|                                                   Ticks_test.mq5 |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
bool is_book;
MqlTick ticks[];
ulong last_time, mem_cnt;
bool is_first;
int t_cnt, result;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  is_book = MarketBookAdd(Symbol());
  result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
  if(result > 0)
  {
    last_time = ulong(ticks[0].time_msc);
    is_first = true;
  }
  else
  {
    is_first = false;
    Alert("No start time!");
    return(INIT_FAILED);
  }   
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+ 
//| возвращает строковое описание тика                               | 
//+------------------------------------------------------------------+ 
string GetTickDescription(MqlTick &tick) 
  { 
   string res = string(tick.time) + "." +  string(tick.time_msc%1000); 
// 
   bool buy_tick = ((tick.flags&TICK_FLAG_BUY)==TICK_FLAG_BUY); 
   bool sell_tick = ((tick.flags&TICK_FLAG_SELL)==TICK_FLAG_SELL); 
   bool ask_tick = ((tick.flags&TICK_FLAG_ASK)==TICK_FLAG_ASK); 
   bool bid_tick = ((tick.flags&TICK_FLAG_BID)==TICK_FLAG_BID); 
   bool last_tick = ((tick.flags&TICK_FLAG_LAST)==TICK_FLAG_LAST); 
   bool volume_tick = ((tick.flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME); 
// 
   if((buy_tick== true) || (sell_tick == true)) 
   { 
     res = res + (buy_tick?StringFormat(" Buy Tick: Last=%G Volume=%d ",tick.last,tick.volume):""); 
     res = res + (sell_tick?StringFormat(" Sell Tick: Last=%G Volume=%d ",tick.last,tick.volume):""); 
     res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):""); 
     res = res + (bid_tick?StringFormat(" Bid=%G ",tick.ask):""); 
   } 
   else 
   { 
     res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):""); 
     res = res + (bid_tick?StringFormat(" Bid=%G ",tick.ask):""); 
     res = res + (last_tick?StringFormat(" Last=%G ",tick.last):""); 
     res = res + (volume_tick?StringFormat(" Volume=%d ",tick.volume):""); 
   } 
   return res; 
  } 
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol());
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
//void OnTick()
void OnBookEvent(const string &symbol)
{
  if(Symbol() == symbol)
  {
    if(is_first == true)
    {
      result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
      if(result > 0)
      {
        Print("First packet of ticks:");
        t_cnt = 0;
        for(int i= 0; i<result; i++)
        {
          if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++;
          Print(GetTickDescription(ticks[i]));
        }
        is_first = false;
        last_time = ulong(ticks[0].time_msc);
      } 
    }
    else
    {
      result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
      if(result > 0)
      {
        if(result > t_cnt)
        {
          mem_cnt = t_cnt;
          t_cnt = 0;
          for(int i= 0; i<(result - int(mem_cnt)); i++)
          {
            if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++;
            Print(GetTickDescription(ticks[i]));
          } 
          if(last_time == ulong(ticks[0].time_msc))
          {
            t_cnt += int(mem_cnt);
          }
          else last_time = ulong(ticks[0].time_msc + 1);
        }
        else
        {
          t_cnt = 0;
          last_time++;
        }
      }
      else
      {
        t_cnt = 0;
        last_time++;
      }
    }
  }
}
//+------------------------------------------------------------------+
 

Pour comparer le fonctionnement du collecteur de ticks, vous pouvez en faire un ruban de tous les échanges à un moment donné

(en remplaçant COPY_TICKS_ALL par COPY_TICKS_TRADE à deux endroits) et comparez-le avec le ruban des métiers,

intégré dans le verre de l'instrument.

Si l'instrument est très liquide, les tirages peuvent être effectués avec un long délai.

 
prostotrader:
 if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) {Print("Tick is ", "TICK_FLAG_ASK", " Tick time: ", ticks[i].time, ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) {Print("Tick is ", "TICK_FLAG_BID", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) {Print("Tick is ", "TICK_FLAG_BUY", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) {Print("Tick is ", "TICK_FLAG_LAST", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) {Print("Tick is ", "TICK_FLAG_SELL", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) {Print("Tick is ", "TICK_FLAG_VOLUME", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else

Les tiques ne peuvent-elles pas avoir plus d'un drapeau à la fois ?

 
prostotrader:

Répéter

OnBookEvent() est exactement le genre de garantie qu'un nouveau lot de tics estarrivé!


Mais est-ce que cela signifie qu'il y a une garantie que vous allez traiter TOUS les événements OnBookEvent ?