Test des "CopyTicks". - page 22

 
fxsaber:
Non, malheureusement. Renat a fait valoir que le verre est diffusé en permanence pour l'ensemble du marché. Mais ce n'est pas une solution rapide (gaspillage) pour la plupart des situations.

C'est la seule option possible. Les enjeux du streaming sont un flux natif et indissociable des tics.

Tout ce qui se trouve dans la plate-forme est interconnecté et nécessite une synchronisation globale des données. Et le flux de tiques joue un rôle crucial à cet égard.

 
Renat Fatkhullin:

C'est la seule option possible. Le streaming des taux est un flux natif et indissociable des tics.

Tout ce qui se trouve dans la plate-forme est interconnecté et nécessite une synchronisation globale des données. Et le flux de tiques joue un rôle essentiel à cet égard.

Et si aucun EA n'est abonné à BookEvent ?

Recommandez-vous de couper MarketWatch pour améliorer les performances ?

 
Renat Fatkhullin:

Mais surtout, les calculs de fréquence d'échantillonnage ci-dessus ne sont pas pertinents. Ils sont faits si maladroitement (en mesurant tout sauf le temps de CopyTicks), que c'en est même surprenant.

Je n'ai pas regardé les calculs de vitesse, je vais me mesurer moi-même en utilisant la méthode que vous avez décrite ci-dessus.
 
fxsaber:

Et si aucun EA n'est abonné à BookEvent ?

Recommandez-vous de couper Marketwatch pour améliorer les performances ?

Coupe-le si tu veux.

 
Renat Fatkhullin:

C'est comme ça qu'on teste les CopyTicks :

MqlTick ExtArr[2048];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   ulong from   =(TimeTradeServer()-1200)*1000;
   ulong ticks  =GetMicrosecondCount();
   int   records=CopyTicks(_Symbol,ExtArr,COPY_TICKS_INFO,from,2048);

   ticks=GetMicrosecondCount()-ticks;
   Print("Time: ",ticks," msc for ",records," records");
  }

Voici le résultat en microsecondes : 95 microsecondes par échantillon de 2048 ticks INFO pour les 20 dernières minutes.

2016.10.18 14:15:38.673 TEST (USDCHF,M1)        Time: 95 msc for 1206 records
C'est radicalement différent des dizaines de millisecondes que vous prétendez. C'est parce que vous n'avez pas mesuré les CopyTicks.

J'ai déjà mangé mon œil de chat sur ce sujet. J'ai fait beaucoup de tests avec CopyTicks. Cette fois, j'ai décidé qu'il suffisait de faire fonctionner l'indicateur.

Votre variante.

Network 'xxx': authorized on MetaQuotes-Demo through Access Point EU Amsterdam (ping: 54.84 ms)

2016.10.18 14:29:11.966 Test14 (GBPUSD,M1)      Time: 20263 msc for 2048 records
2016.10.18 14:29:10.841 Test14 (GBPUSD,M1)      Time: 13190 msc for 2048 records
2016.10.18 14:29:07.788 Test14 (GBPUSD,M1)      Time: 13344 msc for 2048 records
2016.10.18 14:29:07.738 Test14 (GBPUSD,M1)      Time: 12751 msc for 2048 records
 

Il s'agit d'entrer dans une cachette proche pour les 4096 dernières citations.

Tout ce qui y entre prend des microsecondes, et tout ce qui est plus long nécessite un accès à l'historique (y compris le disque).

Par conséquent, mon exemple de récupération des ticks pour 20 min. sur USDCHF, qui est rarement mis à jour, était dans le cache, mais sur GBPUSD, il dépassait déjà les 4096 derniers ticks et devait aller dans la base de données lointaine.

Si je fixe ulong de =(TimeTradeServer()-600)*1000, alors cela conviendra aussi pour le GBPUSD.

 
Renat Fatkhullin:

Il s'agit d'entrer dans une cachette proche pour les 4096 dernières citations.

Tout ce qui y entre prend des microsecondes, et tout ce qui est plus nécessite un accès à l'historique (y compris le disque).

Sur votre démo, c'est effectivement le cas. Sur BCS, ce n'est pas le cas.

Network 'xxx': authorized on BCS-MetaTrader5 through Access Server #2 (ping: 46.66 ms)


2016.10.18 15:12:32.949 Test14 (Si-12.16,M1)    Time: 29089 msc for 1503 records
2016.10.18 15:12:32.822 Test14 (Si-12.16,M1)    Time: 33207 msc for 1501 records
2016.10.18 15:12:32.639 Test14 (Si-12.16,M1)    Time: 21389 msc for 1500 records
2016.10.18 15:12:31.959 Test14 (Si-12.16,M1)    Time: 21926 msc for 1500 records

Et sur Alpari, ce n'est pas bon du tout.

Network 'xxx': authorized on Alpari-MT5 through mt5.nl.3 (ping: 61.87 ms)

2016.10.18 15:14:47.159 Test14 (GBPUSD,M1)      Time: 31086 msc for 1836 records
2016.10.18 15:14:46.999 Test14 (GBPUSD,M1)      Time: 30698 msc for 1836 records
2016.10.18 15:14:46.779 Test14 (GBPUSD,M1)      Time: 46306 msc for 1836 records
2016.10.18 15:14:46.612 Test14 (GBPUSD,M1)      Time: 30440 msc for 1836 records
2016.10.18 15:14:46.532 Test14 (GBPUSD,M1)      Time: 36227 msc for 1836 records

Par conséquent, mon exemple de récupération des ticks pour 20 minutes sur l'USDCHF rarement mis à jour tient dans le cache, mais pour le GBPUSD, il a déjà dépassé les 4096 derniers ticks et m'oblige à aller dans une base de données distante.

J'ai commenté plus haut les inconvénients de Copytix. L'indicateur présenté ralentit car il est obligé d'appeler copyix plusieurs fois. Et tous les décalages sont dus à ça. Voici la raison

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Test des "CopyTicks".

fxsaber, 2016.10.11 19:23

Quel est l'algorithme optimal (le plus rapide) pour obtenir les ticks de_time à_time ?

Une solution a été proposée

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Test des "CopyTicks".

fxsaber, 2016.10.12 08:44

Lorsque non-zéro De l'intérieur CopyTicks cherche (probablement une recherche binaire) un endroit pour commencer - un index dans la base interne.

Veuillez ajouter une fonction qui renvoie l'index dans la base de données par heure. Il sera alors possible de résoudre cette tâche de manière optimale

Maintenant, pour télécharger les ticks entre les dates, nous devons faire des requêtes pour TOUT nombre de ticks, à partir de la date de début. Et ensuite, vérifiez à chaque fois, s'il a atteint la date limite. Et en tenant compte du fait que chaque demande copytix est très chère, et vous obtenez de tels freins.

 
fxsaber:

Et sur Alpari, ce n'est pas bon du tout.

Alpari a été réparé, il semble. BCS ne l'a pas fait.

Il serait bon d'avoir un cache des données copiées demandées précédemment. Eh bien, si la copie se fait en plusieurs étapes (de[i] à de[i+ 1]), il serait logique de mettre beaucoup de choses en cache après la première requête.

En somme, la manière dont la fonction est organisée en interne n'est pas claire. Mais il est difficile de travailler avec elle - à 100%.

 
Conseiller
long LastTime = 0; // time_msc-время последнего тика (самого свежего), полученного из истории
int Count = 0;     // Количество тиков в последенем запросе, у которых time_msc == LastTime

// Возвращает свежие тики, пришедшие после предыдущего вызова
int GetFreshTicks( MqlTick &Ticks[], const uint flags = COPY_TICKS_INFO, const uint count = 2000 )
{
  int Res = 0;

  MqlTick NewTicks[];
  const int NewAmount = CopyTicks(Symbol(), NewTicks, flags, LastTime, count);

  if ((NewAmount > 0) && (Count < NewAmount))
  {
    Res = ArrayCopy(Ticks, NewTicks, 0, Count);

    // Взяли крайнее время из текущей истории
    LastTime = NewTicks[NewAmount - 1].time_msc;
    Count = 1;

    // Находим (Count) в текущей истории количество тиков со временем LastTime
    for (int i = NewAmount - 2; i >= 0; i--)
    {
      if (NewTicks[i].time_msc < LastTime)
        break;

      Count++;
    }
  }

  return(Res);
}

#define TOSTRING(A) " " + #A + " = " + (string)(A)

void OnTick( void )
{
  // возьмем тики с начала утренней сессии
  LastTime = (TimeCurrent() - (TimeCurrent() % (24 * 3600))) * 1000;
  
  MqlTick Ticks[];

  int i = 0;
  int Sum = 0;

  const ulong StartTime  =GetMicrosecondCount();
  
  // Взяли свеженькие тики
  int Amount = GetFreshTicks(Ticks);
    
  while (Amount > 0)
  {
    Sum += Amount;
    i++;
    
    Print(TOSTRING(i) + TOSTRING(Amount) + TOSTRING(Sum) + TOSTRING(GetMicrosecondCount() - StartTime));
    
    // Взяли свеженькие тики  
    Amount = GetFreshTicks(Ticks);    
  }  
}
Résultat sur Metaquotes-demo
2016.10.18 16:06:18.744 Test15 (GBPUSD,M1)       i = 40 Amount = 1453 Sum = 79414 GetMicrosecondCount()-StartTime = 584393
2016.10.18 16:06:18.744 Test15 (GBPUSD,M1)       i = 39 Amount = 1999 Sum = 77961 GetMicrosecondCount()-StartTime = 584314
2016.10.18 16:06:18.729 Test15 (GBPUSD,M1)       i = 38 Amount = 1999 Sum = 75962 GetMicrosecondCount()-StartTime = 568509
2016.10.18 16:06:18.714 Test15 (GBPUSD,M1)       i = 37 Amount = 1999 Sum = 73963 GetMicrosecondCount()-StartTime = 552582
2016.10.18 16:06:18.696 Test15 (GBPUSD,M1)       i = 36 Amount = 1999 Sum = 71964 GetMicrosecondCount()-StartTime = 536790
2016.10.18 16:06:18.681 Test15 (GBPUSD,M1)       i = 35 Amount = 1999 Sum = 69965 GetMicrosecondCount()-StartTime = 520432
2016.10.18 16:06:18.666 Test15 (GBPUSD,M1)       i = 34 Amount = 1999 Sum = 67966 GetMicrosecondCount()-StartTime = 504725
2016.10.18 16:06:18.649 Test15 (GBPUSD,M1)       i = 33 Amount = 1999 Sum = 65967 GetMicrosecondCount()-StartTime = 488911
2016.10.18 16:06:18.634 Test15 (GBPUSD,M1)       i = 32 Amount = 1999 Sum = 63968 GetMicrosecondCount()-StartTime = 473372
2016.10.18 16:06:18.619 Test15 (GBPUSD,M1)       i = 31 Amount = 1999 Sum = 61969 GetMicrosecondCount()-StartTime = 458022
2016.10.18 16:06:18.604 Test15 (GBPUSD,M1)       i = 30 Amount = 1999 Sum = 59970 GetMicrosecondCount()-StartTime = 442557
2016.10.18 16:06:18.589 Test15 (GBPUSD,M1)       i = 29 Amount = 1999 Sum = 57971 GetMicrosecondCount()-StartTime = 427044
2016.10.18 16:06:18.571 Test15 (GBPUSD,M1)       i = 28 Amount = 1999 Sum = 55972 GetMicrosecondCount()-StartTime = 411524
2016.10.18 16:06:18.556 Test15 (GBPUSD,M1)       i = 27 Amount = 1999 Sum = 53973 GetMicrosecondCount()-StartTime = 396539
2016.10.18 16:06:18.541 Test15 (GBPUSD,M1)       i = 26 Amount = 1999 Sum = 51974 GetMicrosecondCount()-StartTime = 381185
2016.10.18 16:06:18.526 Test15 (GBPUSD,M1)       i = 25 Amount = 1999 Sum = 49975 GetMicrosecondCount()-StartTime = 366146
2016.10.18 16:06:18.511 Test15 (GBPUSD,M1)       i = 24 Amount = 1999 Sum = 47976 GetMicrosecondCount()-StartTime = 351066
2016.10.18 16:06:18.496 Test15 (GBPUSD,M1)       i = 23 Amount = 1999 Sum = 45977 GetMicrosecondCount()-StartTime = 336183
2016.10.18 16:06:18.481 Test15 (GBPUSD,M1)       i = 22 Amount = 1999 Sum = 43978 GetMicrosecondCount()-StartTime = 321109
2016.10.18 16:06:18.466 Test15 (GBPUSD,M1)       i = 21 Amount = 1999 Sum = 41979 GetMicrosecondCount()-StartTime = 306119
2016.10.18 16:06:18.449 Test15 (GBPUSD,M1)       i = 20 Amount = 1999 Sum = 39980 GetMicrosecondCount()-StartTime = 288558
2016.10.18 16:06:18.434 Test15 (GBPUSD,M1)       i = 19 Amount = 1999 Sum = 37981 GetMicrosecondCount()-StartTime = 273758
2016.10.18 16:06:18.419 Test15 (GBPUSD,M1)       i = 18 Amount = 1999 Sum = 35982 GetMicrosecondCount()-StartTime = 259255
2016.10.18 16:06:18.406 Test15 (GBPUSD,M1)       i = 17 Amount = 1999 Sum = 33983 GetMicrosecondCount()-StartTime = 244750
2016.10.18 16:06:18.391 Test15 (GBPUSD,M1)       i = 16 Amount = 1999 Sum = 31984 GetMicrosecondCount()-StartTime = 230100
2016.10.18 16:06:18.371 Test15 (GBPUSD,M1)       i = 15 Amount = 1999 Sum = 29985 GetMicrosecondCount()-StartTime = 216143
2016.10.18 16:06:18.361 Test15 (GBPUSD,M1)       i = 14 Amount = 1999 Sum = 27986 GetMicrosecondCount()-StartTime = 201830
2016.10.18 16:06:18.346 Test15 (GBPUSD,M1)       i = 13 Amount = 1999 Sum = 25987 GetMicrosecondCount()-StartTime = 186887
2016.10.18 16:06:18.331 Test15 (GBPUSD,M1)       i = 12 Amount = 1999 Sum = 23988 GetMicrosecondCount()-StartTime = 172667
2016.10.18 16:06:18.311 Test15 (GBPUSD,M1)       i = 11 Amount = 1999 Sum = 21989 GetMicrosecondCount()-StartTime = 158356
2016.10.18 16:06:18.299 Test15 (GBPUSD,M1)       i = 10 Amount = 1999 Sum = 19990 GetMicrosecondCount()-StartTime = 143450
2016.10.18 16:06:18.289 Test15 (GBPUSD,M1)       i = 9 Amount = 1999 Sum = 17991 GetMicrosecondCount()-StartTime = 128520
2016.10.18 16:06:18.269 Test15 (GBPUSD,M1)       i = 8 Amount = 1999 Sum = 15992 GetMicrosecondCount()-StartTime = 114209
2016.10.18 16:06:18.256 Test15 (GBPUSD,M1)       i = 7 Amount = 1999 Sum = 13993 GetMicrosecondCount()-StartTime = 100016
2016.10.18 16:06:18.246 Test15 (GBPUSD,M1)       i = 6 Amount = 1999 Sum = 11994 GetMicrosecondCount()-StartTime = 85745
2016.10.18 16:06:18.231 Test15 (GBPUSD,M1)       i = 5 Amount = 1999 Sum = 9995 GetMicrosecondCount()-StartTime = 71438
2016.10.18 16:06:18.219 Test15 (GBPUSD,M1)       i = 4 Amount = 1999 Sum = 7996 GetMicrosecondCount()-StartTime = 57293
2016.10.18 16:06:18.204 Test15 (GBPUSD,M1)       i = 3 Amount = 1999 Sum = 5997 GetMicrosecondCount()-StartTime = 43192
2016.10.18 16:06:18.181 Test15 (GBPUSD,M1)       i = 2 Amount = 1999 Sum = 3998 GetMicrosecondCount()-StartTime = 28943
2016.10.18 16:06:18.171 Test15 (GBPUSD,M1)       i = 1 Amount = 1999 Sum = 1999 GetMicrosecondCount()-StartTime = 15160
80K ticks en une demi-seconde - lent ! Dire que nous aurions dû demander plus de ticks au lieu de 2000 ticks à la fois est bien sûr possible. Quelle est alors la valeur optimale de la demande ?
 
fxsaber:
80K ticks en une demi-seconde, c'est lent ! Dire qu'il fallait demander non pas 2000 ticks à la fois, mais plus, c'est bien sûr possible. Quelle valeur de requête est alors optimale ?

Il est optimal de télécharger une fois ce dont vous avez besoin au plus profond de vous-même, puis de n'en télécharger de nouveaux depuis le cache voisin qu'en quelques microsecondes.

Si, à chaque fois, vous faites des requêtes profondes en tombant sur le disque, alors bien sûr, c'est de votre propre faute.