Rejoignez notre page de fans
MathTicker - générateur de tic-tac en mode mathématique - bibliothèque pour MetaTrader 5
- Vues:
- 45
- Note:
- Publié:
-
Besoin d'un robot ou d'un indicateur basé sur ce code ? Commandez-le sur Freelance Aller sur Freelance
Alternative à la bibliothèque EAToMath https://www.mql5.com/fr/code/61283
Enregistre les ticks en mode ticks réels et les lit en mode mathématique en appelant votre stratégie à chaque tick enregistré.
Raison de la création : testeur MQ, écrit des fichiers de données de ticks sur chaque agent à chaque fois que l'optimiseur est exécuté. J'ai 36 agents qui écrivent 10 Go chacun pour l'un des outils et la période de test, soit un total de 360 Go sur un disque de 480 Go. Ce processus prend environ une heure avant chaque optimisation. Les disques SSD classiques ont une durée de vie de 500 à 1 000 cycles d'écriture. En réécrivant 360 Go à chaque fois, la ressource sera épuisée très rapidement. Cette bibliothèque n'écrit qu'un seul fichier et les 36 agents lisent ensuite les données de ce fichier. C'est pour toutes ces raisons que nous avons écrit cette bibliothèque : nous n'utilisons qu'un seul fichier + économie d'une heure pour l'écriture des données à chaque agent + accélération par rapport à MQ tester et même à Virtual en mode ticks réels.
Le problème a été étudié simultanément avec fxsaber (l'auteur d'EAToMath), chacun avec sa propre version. Mon code est plus clair pour moi, c'est pourquoi je l'utilise.
Pour les opérations de trading, la bibliothèque MT4Orders est utilisée https://www.mql5.com/fr/code/16006
Pour le trading virtuel, il est nécessaire d'utiliser la bibliothèque Virtual https://www.mql5.com/fr/code/22577
Pour visualiser les résultats du trading, vous pouvez utiliser MT4Orders QuickReport https://www.mql5.com/fr/code/47816 ou Report
Pour compresser les ticks TickCompressorhttps://www.mql5.com/fr/code/66201
Pour supprimer les ticks éventuellement inutiles La bibliothèque Control_Trade_Sessions https://www.mql5.com/fr/code/48059 est connectée, par exemple, si une session de cotation est plus grande qu'une session de trading. Elle peut également être supprimée si tous les ticks sont utilisés, c'est-à-dire si les sessions coïncident.
Différences par rapport à EAToMath :
Avantages :
- Le code est plus court et plus simple, avec seulement 5 bibliothèques de plug-in. Si vous devez le modifier, il sera plus facile à comprendre.
- Les données sont mieux compressées grâce à un algorithme différent https://www.mql5.com/fr/code/66201. En sauvegardant seulement time_msc, ask et bid - jusqu'à 86% des ticks sont sauvegardés sous la forme de 3 chars, c'est-à-dire 3 octets. Taille moyenne par tick = 3,266 octets lors de la sauvegarde des données de tick de BTCUSDT pour 2023.
Lors de la sauvegarde avec les volumes, la moyenne est de 4,835 octets. Et lors de l'enregistrement d'un tick complet = 8,439 octets. Vous trouverez ci-dessous le tableau des résultats des tests.
En outre, vous pouvez utiliser l'archivage ZIP intégré. La taille du fichier est réduite de deux fois. Un tel fichier prend 245 Mo, alors que la somme des tailles de fichiers en .tcs pour 2023 prend 364 Mo, c'est-à-dire que la compression est 1,5 fois supérieure à celle de MQ. Et la vitesse de génération des tics dans le mode mathématique est ~2 fois plus rapide. Voir le tableau ci-dessous. - Il y a plus d'options de sauvegarde :

- Le fichier peut être sauvegardé sur un disque SSD ou RAM en créant un lien dans le système. Les fichiers peuvent prendre beaucoup d'espace et le disque RAM peut ne pas suffire, vous pouvez donc choisir d'enregistrer sur le disque principal. Les vitesses de lecture du SSD et de la RAM sont à peu près les mêmes. J'ai lu que le SSD mettait en cache jusqu'à 5 % de la capacité totale des données les plus fréquemment demandées.
Le SSD s'use un peu lors de la lecture, car il faut écraser des cellules de mémoire plus souvent que lorsqu'on stocke sans lire. Je ne connais pas les chiffres exacts, mais par exemple 1 écrasement pour 10 lectures ou pour 1000 lectures.... Mais cela n'a que peu d'importance par rapport à l'usure du disque par le testeur MQ.
Inconvénients :
- La connexion de Virtual doit être effectuée par vous-même (instructions ici https://www.mql5.com/fr/code/22577), EAToMath transmettra votre stratégie à Virtual lui-même.
La vitesse de la variante BidAsk est comparable à celle d'EAToMath. Les autres variantes sont plus lentes car elles contiennent plus de données ou ont une compression ZIP supplémentaire.
Caractéristiques d'utilisation :
Vous ne pouvez pas utiliser les fonctions standard Symbol(), Digits( ) (=4), Point() (=0.0001) dans la stratégie, car elles produiront des valeurs par défaut, sans rapport avec le symbole testé. A la place, utilisez _Symbol, _Digits, _Point qui sont remplacés par les valeurs lues dans le fichier. De plus, de nouvelles constantes _TickSize et _TickValue avec les valeurs du symbole enregistré ont été ajoutées - elles sont nécessaires pour le calcul correct du profit, de la commission et des swaps dans la devise de dépôt.
L'ordre de travail avec la période de test sélectionnée lors de l'enregistrement des ticks :
- Sélectionnez le mode de test par ticks réels, l'instrument requis et les dates de test. Réglez la variable Task sur Save et sélectionnez l'option de sauvegarde des ticks. Démarrez le testeur. Un fichier contenant les ticks sera ensuite créé dans le dossier spécifié.
- Réglez la variable Tâche sur Exécuter_Stratégie. Vous pouvez quitter le mode en réalisant des ticks pour les comparer plus tard. Démarrez le testeur. Les calculs sont effectués à partir de ticks réels, et non à partir du fichier. Obtenez le résultat.

- Réglez le mode de test sur les calculs mathématiques. Démarrez le testeur. Les calculs sont effectués à partir de ticks provenant du fichier. Comparez avec le résultat de l'étape 2 : il devrait être identique, mais plusieurs fois plus rapide.
Ordre de travail avec l'archive :
- Créer une archive avec tous les ticks de l'historique : Sélectionner le mode de test par ticks réels, l'instrument requis. Définir les dates de test de <= premier tick à >= dernier tick dans l'historique disponible. Définissez la variable Task sur Save...To_Archive et sélectionnez l'option de sauvegarde des ticks. Démarrez le testeur. Ensuite, un dossier portant le nom de l'outil sera créé dans le dossier spécifié, dans lequel les fichiers contenant les tics de chaque année seront sauvegardés. La dernière année peut être écrasée si nécessaire. Pour ce faire, sélectionnez uniquement l'année en cours dans les dates afin d'éviter d'écraser les années précédentes.
- Définissez le mode de test sur Maths. Définissez la variable Task sur Run_Strategy_Fron_Archive.
- Dans le MathTicker : using the full archive group, définissez :
Instrument - to Instrument name (must match the name of the folder where its ticks are stored), start and end date of the test.

- Démarrez le testeur. Les calculs sont effectués à partir des ticks des fichiers annuels requis. Étant donné que le travail est effectué non pas avec un seul fichier, mais avec plusieurs, il est un peu plus lent, car l'ouverture et la fermeture des fichiers prennent du temps. Par exemple, au lieu de 1,7 seconde, il faudra 2,7 secondes pour générer des tics pour 3 ans.
- La somme des ticks obtenue par l'Expert Advisor ci-dessous peut différer d'une petite valeur d'un premier tick. Lorsque vous testez sur des caractères personnalisés en mode ticks réels, le premier tick ne produit que Ask ou Bid (si vous n'avez pas sauvegardé les deux). Lorsque vous testez à partir de l'archive, ils sont tous deux restaurés à partir des ticks précédents.
Un exemple de l'Expert Advisor le plus simple pour estimer la vitesse de travail :
#property tester_no_cache #include <Forester\MathTicker.mqh> // connecter le commerce en mode mathématique input int rep=0;/Répétitions pour optimisation sinput bool AddVolumes=true; void OnInit(){} void OnTick(){ static MqlTick Tick; if (SymbolInfoTick(_Symbol, Tick)){ #ifdef _MathTick_ if(MathTick.SaveTick(Tick)){ return; }//Si nous sauvons des ticks, alors nous sortons et ne faisons pas de transactions. #endif Strategy(Tick); } } double Sum = 0;int tk=0; void Strategy(MqlTick& Tick){ // la stratégie la plus simple - utilisée pour comparer la vitesse de lecture avec EAToMath Sum += Tick.bid+Tick.ask+(AddVolumes?Tick.volume_real:0.0); tk++; //if(tk<100){Print(Tick.time," ",Tick.ask," ",Tick.bid," ",Tick.last," ",Tick.volume_real," ",Tick.flags);} } ulong StartTime = GetMicrosecondCount(); double OnTester(){ #ifdef _MathTick_ // exécuté avec MathTick - il compte les paramètres des symboles du fichier avec des ticks. Pour les tests en mode mat if(MathTick.SaveTicksEnd()){return 0;}// fermer le fichier après l'enregistrement des tics et quitter if(MathTick.ReadSymbolVars()){ MathTick.Ticker();// en mode mat, envoie tous les ticks à Strategy(MqlTick &Tick). } #endif Print("ticks: ",tk); long work_time = (long)(GetMicrosecondCount() - StartTime)/1000; //return(NormalizeDouble(work_time, 1)) ; // pour obtenir la vitesse du travail et le temps de travail. return Sum;// pour comparer les résultats des calculs }
Vous pouvez basculer 1 paramètre :
//#define RestoreFlags // восстановить флаги тика из изменения ask, bid, volume - добавит 7% к времени генерации тиков 931 вместо 869 мс
Lors de la génération de ticks, des statistiques sur la compression des ticks seront affichées.
Vous trouverez ci-dessous les impressions des statistiques, des volumes et de l'heure de génération des ticks.
-----------
Testeur MQsans volumes
pass 1 returned result 4345830621850.311523 in 0:00:08.232
| Compression C ZIP | |
|---|---|
| AskBid. Taille du fichier : 225 mb -------------------- Statistiques : -------------------- 3 bytes : 86.6%, 62644158 ticks 4 bytes : 0.6%, 412167 ticks 5 bytes : 12.7%, 9185484 ticks 6 bytes : 0.0%, 15274 ticks 11 bytes : 0.1%, 46214 ticks 12 bytes : 0.0%, 1 ticks 24 bytes : 0.0%, 1 ticks Total : 72303299 ticks, 236108596 bytes. Moyenne : 3.266 bytes par tick final balance 0.00 USD pass 10 returned result 4345830621850.311523 in 0:00:01.485 no normalisation pass 1 returned result 4345830621850.311523 in 0:00:00.892 | AskBid_Zipped. Taille du fichier : 106 mb -------------------- Statistiques : -------------------- 3 octets : 86.6%, 62644158 ticks 4 octets : 0.6%, 412167 ticks 5 octets : 12.7%, 9185484 ticks 6 octets : 0.0%, 15274 ticks 11 bytes : 0.1%, 46214 ticks 12 bytes : 0.0%, 1 ticks 24 bytes : 0.0%, 1 ticks Total : 72303299 ticks, 236108596 bytes. Moyenne : 3.266 bytes par tick Taille non zippée : 236108596. Taille zippée : 111720863. Compression ZIP : 47.3% pass 10 returned result 4345830621850.311523 in 0:00:02.548 no normalisation pass 2 returned result 4345830621850.311523 in 0:00:01.890 |
Testeur MQ avec volumes
la passe 1 a retourné le résultat 4345879117123.356445 en 0:00:07.962
| Compression C ZIP | |
|---|---|
| AskBidVolume. Taille du fichier : 333 mb -------------------- Statistiques : -------------------- 4 octets : 60.4%, 43684907 ticks 5 octets : 1.1%, 809676 ticks 6 octets : 33.5%, 24194111 ticks 7 octets : 4.9%, 3548666 ticks 8 octets : 0.0%, 7909 ticks 12 octets : 0.1%, 40022 ticks 13 octets : 0.0%, 17964 ticks 14 octets : 0.0%, 2 ticks 19 bytes : 0.0%, 41 ticks 32 bytes : 0.0%, 1 ticks Total : 72303299 ticks, 349571243 bytes. Moyenne : 4.835 bytes par tick pass 1 returned result 4345879117123.356445 in 0:00:02.803 no normalisation pass 4 returned result 4345879117123.356445 in 0:00:01.659 | AskBidVolume_Zipped. Taille du fichier : 204 mb -------------------- Statistiques : -------------------- 4 octets : 60.4%, 43684907 ticks 5 octets : 1.1%, 809676 ticks 6 octets : 33.5%, 24194111 ticks 7 octets : 4.9%, 3548666 ticks 8 octets : 0.0%, 7909 ticks 12 bytes : 0.1%, 40022 ticks 13 bytes : 0.0%, 17964 ticks 14 bytes : 0.0%, 2 ticks 19 bytes : 0.0%, 41 ticks 32 bytes : 0.0%, 1 ticks Total : 72303299 ticks, 349571243 bytes. Moyenne : 4.835 bytes par tick Taille non zippée:349571243. Taille zippée : 214897079. Compression ZIP : 61.5% pass 2 returned result 4345879117123.356445 in 0:00:04.260 no normalisation pass 2 returned result 4345879117123.356445 in 0:00:03.096 |
| Tous. Taille du fichier : 582 mb -------------------- Statistiques : -------------------- 8 octets : 61.5%, 44494583 ticks 9 octets : 33.5%, 24194111 ticks 10 octets : 4.9%, 3548666 ticks 11 octets : 0.0%, 7909 ticks 15 octets : 0.1%, 40022 ticks 16 octets : 0.0%, 17964 ticks 17 octets : 0.0%, 2 ticks 22 bytes : 0.0%, 41 ticks 44 bytes : 0.0%, 1 ticks Total : 72303299 ticks, 610166056 bytes. Moyenne : 8.439 bytes par tick pass 2 returned result 4345879117123.356445 in 0:00:03.768 no normalisation pass 1 returned result 4345879117123.356445 in 0:00:02.256 | All_Zipped. Taille du fichier : 245 mb -------------------- Statistiques : -------------------- 8 octets : 61.5%, 44494583 ticks 9 octets : 33.5%, 24194111 ticks 10 octets : 4.9%, 3548666 ticks 11 octets : 0.0%, 7909 ticks 15 octets : 0.1%, 40022 ticks 16 bytes : 0.0%, 17964 ticks 17 bytes : 0.0%, 2 ticks 22 bytes : 0.0%, 41 ticks 44 bytes : 0.0%, 1 ticks Total : 72303299 ticks, 610166056 bytes. Moyenne : 8.439 bytes par tick Taille non zippée : 610166056. Taille zippée : 257105213. Compression ZIP : 42.1 % pass 1 returned result 4345879117123.356445 in 0:00:05.388 no normalisation pass 10 returned result 4345879117123.356445 in 0:00:03.936 |
La taille des fichiers .tcs pour la même année 2023 :

Toutes les variantes avec ZIP, même l'enregistrement complet des ticks, sont plus compactes (3,5 à 1,5 fois).
Exemple d'Expert Advisor pour le trading virtuel et le rapport de sortie :
#property tester_no_cache #include <MT4Orders.mqh> // https://www.mql5.com/fr/code/16006 #include <Forester\MathTicker.mqh> // connecter le commerce en mode mathématique #define ORDER_CURRENCY_DIGITS 2 // Chiffres pour le calcul du profit/commission/swap lorsqu'il est placé dans l'historique des transactions. #define VIRTUAL_LIMITS_TP_SLIPPAGE // Les Limiteurs et les TP sont exécutés au premier prix d'acceptation - slippages positifs #define ORDER_COMMISSION -0 // Attribution de la commission = Lots * ORDER_COMMISSION. #include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/fr/code/22577 #define REPORT_TESTER // Le testeur enregistrera automatiquement les rapports #define REPORT_BROWSER // Création d'un rapport au démarrage du navigateur - nécessite l'autorisation de la DLL. #define USE_highcharts //- Vous pouvez télécharger et tester gratuitement tous les produits Highcharts. Lorsque votre projet/produit est prêt à être lancé, achetez une licence commerciale. https://shop.highcharts.com/ #include <MT4Orders_QuickReport.mqh>// enum VirtTyp {MQ_Tester=0,Virtual1=1,Virtual2=2}; sinput VirtTyp tester1=1;//Tester 1 sinput VirtTyp tester2=2;//Tester 2 input int rep=0;/Répétitions pour optimisation bool isOptimization = false, isTester=false; double balInit=0; VIRTUAL_POINTER Virtual[10]; void OnInit(){ Virtual[0] = 0; // 0 - environnement commercial réel Virtual[1] = VIRTUAL::Create(AccountBalance()); // Création de la virtualisation 1. Virtual[2] = VIRTUAL::Create(AccountBalance()); // Création de la virtualisation 2. //Virtuel[tester1].Select() ; isOptimization = MQLInfoInteger(MQL_OPTIMIZATION) ; isTester = MQLInfoInteger(MQL_TESTER); balInit=AccountBalance(); } void OnTick(){ //Virtuel[0].Select() ; VIRTUAL::NewTick();// envoyer le tick à la machine virtuelle actuelle static MqlTick Tick; if (SymbolInfoTick(_Symbol, Tick)){ #ifdef _MathTick_ if(MathTick.SaveTick(Tick)){ return; }//lorsque l'écriture des ticks quittera la fonction, Strategy() ne sera pas appelée #endif Strategy(Tick);//négociation } } void Strategy(MqlTick& Tick){ // la stratégie la plus simple - utilisée pour comparer la vitesse de lecture avec EAToMath if(Tick.ask==0 || Tick.bid==0){return;}//Le testeur MQ négocie sur un tick raté, Virtual ne le fait pas. Interdiction pour MQ également if(tester1>0){Virtual[tester1].Select(); VIRTUAL::NewTick(Tick);}// sélectionner la virtualisation 1 et envoyer une coche if(tester2>0){Virtual[tester2].Select(); VIRTUAL::NewTick(Tick);}//sélectionner la virtualisation 2 et envoyer une coche if(isNewHour(Tick.time)){//le premier tic-tac de chaque heure if(GetHour0(Tick.time) % 2==0){// achat aux heures paires dans le testeur 1 Virtual[tester1].Select();//sélectionner la virtualisation 1 OrderSend(_Symbol, OP_BUY, 1, Tick.ask, 0, Tick.ask - 100 * _Point, Tick.ask + 100 * _Point); }else{/vendre à des heures indues dans le testeur 2 Virtual[tester2].Select();//sélectionner la virtualisation 2 OrderSend(_Symbol, OP_SELL, 1, Tick.bid, 0, Tick.bid + 100 * _Point, Tick.bid - 100 * _Point); } } } double OnTester(){ #ifdef _MathTick_ // exécuté avec MathTick - il lira les paramètres du symbole à partir du fichier tick. Pour les tests en mode mat if(MathTick.SaveTicksEnd()){return 0;}//retour après l'enregistrement des ticks if(MathTick.isMath && MathTick.ReadSymbolVars()){ if(tester1==0){Alert(" >>>>>>>>> Virtual tester 1=MQ. In math mode can be used only virtual tester. <<<<<<<<");return 0;} if(tester2==0){Alert(" >>>>>>>>> Virtual tester 1=MQ. In math mode can be used only virtual tester. <<<<<<<<");return 0;} SYMBOL_BASE sb; sb.Point=_Point; sb.Digits=_Digits; sb.Symbol=_Symbol; sb.SymbolID=0; sb.TickSize=_TickSize; sb.TickValue=_TickValue / _TickSize;//this.TickValue_ /= this.TickSize_ ; //comme dans SetSymbol() dans \fxsaber\Virtual\Symbol_Base.mqh Virtual[1].Select(); VIRTUAL::SetSymbolBase(sb); Virtual[2].Select(); VIRTUAL::SetSymbolBase(sb); //minFreezeLevel = _minFreezeLevel*_Point ; minStopLevel = _minStopLevel*_Point ; Virtual[tester1].Select(); MathTick.Ticker();// en mode mat, envoie tous les ticks à Strategy(MqlTick &Tick). } #endif double ret_val=0; for (int v = 0 ; v <= VIRTUAL::Total(); v++){ if(Virtual[v].Select()){ if(v > 0){ VIRTUAL::Stop(); #ifdef _MathTick_ // exécuté avec MathTick - il lira les paramètres du symbole à partir du fichier tick. Pour les tests en mode mat if(MathTick.isMath){ VIRTUAL::CalcSwaps( MathTick.swapShort, MathTick.swapLong, 0, MathTick.swap3days ); }//échanges à partir du fichier tick else{VIRTUAL::CalcSwaps( _Symbol, 0 );} #else VIRTUAL::CalcSwaps( _Symbol, 0 );//calculer les swaps - toutes les transactions ont un swap, c'est-à-dire que si 2+ instruments différents, ils auront tous les deux le swap du symbole principal. #endif }// clôture des transactions incomplètes au prix du dernier tick, comme dans le testeur if( !isOptimization){QuickReport("report_"+(string)v, true, v,false,true);} Print((string)v+" AccountBalance = ",AccountBalance(), " AccountEquity = ",AccountEquity()); double prib=AccountBalance()-balInit; ret_val += prib; // }} return ret_val;// pour comparer les résultats des calculs } bool isNewHour (datetime &t){ static int next_h=-1; if(t < next_h){ return false; } else { next_h = (GetHour0(t)+1)*3600;return true;}} int GetHour0 (datetime &t){return((int)( t / 3600));}/heure courante du 1er janvier 1971
Cet exemple crée 2 machines virtuelles avec des transactions différentes. Aux heures paires, l'un des testeurs achète, l'autre vend aux heures impaires.
Il s'agit d'un exemple complexe avec 2 testeurs, il peut être simplifié si vous avez besoin de travailler avec un seul testeur.
Vous pouvez également sélectionner le testeur MQ et le comparer aux résultats des testeurs virtuels pour contrôler l'exactitude des calculs. Seule la commission peut ne pas coïncider, car il existe de nombreuses commissions différentes et une seule variante est programmée dans le testeur virtuel.
Traduit du russe par MetaQuotes Ltd.
Code original : https://www.mql5.com/ru/code/65821
EMA_ATR_VA
Moyenne mobile exponentielle adaptative - ATR Volatilité ajustée par Jose Silva sur la base de l'indicateur ATR.
EMA_STD_VA
Moyenne exponentielle adaptative en fonction de la valeur de l'écart-type.
SAR ADX Signal
Signal SAR ADX avec notification mobile, réécrit à partir de la version MT4 (source introuvable). Cet indicateur peut être repeint, soyez prudent lors de son utilisation.
EMA_BB_VA
Moyenne mobile exponentielle adaptative (dépendante des bandes de Bollinger) (BB Volatility Adjusted by Jose Silva).