- www.mql5.com
if (prev_calculated) EventChartCustom(Chart, 0, Index, 0, NULL);Il peut arriver que vous manquiez des ticks si l'événement n'est pas mis en file d'attente. Cela arrive parfois (surtout sur un VPS ou un ordinateur lent).
Malheureusement, même les experts conseillers simples dotés uniquement de la fonction OnTick peuvent manquer des ticks. Pour les experts conseillers de trading, on utilise les fonctions CopyTicks et d’autres astuces afin qu’ils fonctionnent sans manquer de ticks.
Cette bibliothèque garantit de ne pas manquer de ticks uniquement dans le Testeur. Tout fonctionne exactement comme avec OnTick.
/* // https://www.mql5.com/ru/blogs/post/755348 #define VIRTUAL_TESTER_MULTI // Lancement dans l'environnement de trading virtuel OnTickMulti #define VIRTUAL_LIMITS_TP_SLIPPAGE // Les ordres stop et TP sont exécutés au premier cours accepté - slippage positif #define VIRTUAL_CLOSEALL_BYEND // Ferme de force tous les ordres à la fin du test // #define VIRTUAL_ALTERNATIVE // Vitesse de calcul alternative */ #include <MT4Orders.mqh> // https://www.mql5.com/fr/code/16006 #include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/fr/code/47647 /* #define REPORT_TESTER // Les rapports seront automatiquement enregistrés dans le testeur #define REPORT_BROWSER // Création d'un rapport avec le lancement du navigateur - nécessite l'autorisation de la DLL. #include <Report.mqh> // https://www.mql5.com/fr/code/18801 */ input group "Trading" input double LotSize=0.01; input double TPdist=0.1; // TP (%) input double SLdist=0.2; // SL (%) input long MyMagic=123; input group "Benchmark: https://www.mql5.com/ru/forum/282062/page49#comment_50801337" input int inRange = 0; // OnTick multi-caractères. void OnTickMulti( const string &Symb, const int &Index ) { TradeStep(Symb, Index); } double OnTester() { return AccountInfoDouble(ACCOUNT_BALANCE); } int GetHour( const datetime time ) { return((int)(time / 3600) % 24); } void TradeStep( const string &symbol, const int &Index ) { if(GetHour(TimeTradeServer()) < 2) return; DoTrade(symbol, Index); } bool IsMySymbol( const string &Symb, const int &Index ) { return(OnTickMulti.IsOnlySymbolBase || ( #ifdef __VIRTUAL__ VIRTUAL::GetHandle() ? (OrderSymbolID() == Index) : // https://www.mql5.com/ru/forum/282062/page52#comment_51051261 #endif // #ifdef __VIRTUAL__ (OrderSymbol() == Symb))); } void DoTrade(const string &symbol, const int &Index ) { int total=OrdersTotal(); bool haveBuy=false; bool haveSell=false; for(int i=0; i<total; i++) { if(OrderSelect(i, SELECT_BY_POS) && OrderMagicNumber()==MyMagic && IsMySymbol(symbol, Index)) { int type=OrderType(); if(type==OP_BUY) haveBuy=true; if(type==OP_SELL) haveSell=true; } } if(!haveBuy) { double price=SymbolInfoDouble(symbol,SYMBOL_ASK); int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double tp=NormalizeDouble(price*(1.0+TPdist/100.0), digits); double sl=NormalizeDouble(price*(1.0-SLdist/100.0), digits); OrderSend( symbol, OP_BUY, LotSize, price, 0, sl, tp, NULL, MyMagic); } if(!haveSell) { double price=SymbolInfoDouble(symbol,SYMBOL_BID); int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double tp=NormalizeDouble(price*(1.0-TPdist/100.0), digits); double sl=NormalizeDouble(price*(1.0+SLdist/100.0), digits); OrderSend( symbol, OP_SELL, LotSize, price, 0, sl, tp, NULL, MyMagic); } }
Paramètres du Tester.
Accélération.
Il est possible d'accélérer le code en décommentant quelques lignes au début.
| Configuration | Résultat |
|---|---|
| Sans Virtual.mqh. | temps de passage le plus court : 0:00:13,184, temps de passage le plus long : 0:00:15,031, temps de passage moyen : 0:00:13,633 |
| Avec Virtual.mqh, inVirtualTester = false. | passage le plus court 0:00:14,735, passage le plus long 0:00:16,384, passage moyen 0:00:15,081 |
| Avec Virtual.mqh, inVirtualTester = true. | meilleur temps: 0:00:05,872, temps le plus long : 0:00:05,964, temps moyen : 0:00:05,919 |
| Avec Virtual.mqh, inVirtualTester = true + VIRTUAL_ALTERNATIVE. | meilleur temps 0:00:06,172, pire temps 0:00:07,791, temps moyen 0:00:06,524 |
Le robot est extrêmement simple (0 à 2 positions ouvertes par symbole avec des SL/TP fixes, sans ordres différés) ; c'est pourquoi, dans cette configuration, il n'est possible d'obtenir qu'un gain de vitesse de 2,5 fois.
TickValue+Swap+Commission.
Les tests ci-dessus ont été effectués en mode « par pips » (voir la capture d'écran des paramètres), afin de ne pas avoir à recalculer la TickValue à chaque tick en connectant d'autres instruments pour cela. Dans ce mode, les résultats sont identiques.
Si vous recherchez une accélération maximale, c'est cette solution qu'il vous faut.
- 2023.12.25
- www.mql5.com
Forum consacré au trading, aux systèmes de trading automatisés et au test des stratégies de trading
fxsaber, 18/03/2024 18h36
void DoTrade(const string &symbol, const int &Index ) { int total=OrdersTotal(); bool haveBuy=false; bool haveSell=false; for(int i=0; i<total; i++) { if(OrderSelect(i, SELECT_BY_POS) && (OrderMagicNumber()==Index)) { int type=OrderType(); if(type==OP_BUY) haveBuy=true; if(type==OP_SELL) haveSell=true; } } if(!haveBuy) { double price=SymbolInfoDouble(symbol,SYMBOL_ASK); int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double tp=NormalizeDouble(price*(1.0+TPdist/100.0), digits); double sl=NormalizeDouble(price*(1.0-SLdist/100.0), digits); OrderSend( symbol, OP_BUY, LotSize, price, 0, sl, tp, NULL, Index); } if(!haveSell) { double price=SymbolInfoDouble(symbol,SYMBOL_BID); int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double tp=NormalizeDouble(price*(1.0-TPdist/100.0), digits); double sl=NormalizeDouble(price*(1.0+SLdist/100.0), digits); OrderSend( symbol, OP_SELL, LotSize, price, 0, sl, tp, NULL, Index); } }
| Configuration | Résultat |
|---|---|
| Sans Virtual.mqh. | passage le plus court 0:00:13.184, passage le plus long 0:00:15.031, passage moyen 0:00:13.633 |
J'ai mis en évidence ci-dessus dans le code une méthode simple pour accélérer un expert multidevises sans aucune bibliothèque Virtual.
| Configuration | Résultat |
|---|---|
| Sans Virtual.mqh +MagicNumberOrderSymbol | passage le plus court 0:00:08,608, passage le plus long 0:00:10,236, durée moyenne d'un passage 0:00:08,942 |
Un gain de vitesse gratuit de 1,5 fois !
J'ai vérifié le ralentissement du Tester lors du passage du mode mono-symbole au mode multi-symboles. Je ne l'ai pas fait de manière tout à fait optimale : le conseiller est factice.
Expert advisor monosymbole.
#property tester_no_cache input group "Benchmark: https://www.mql5.com/ru/forum/282062/page49#comment_50801337" input int inRange = 0; const ulong StartTime = GetMicrosecondCount(); int AmountTicks = 0; double OnTester() { return((double)(GetMicrosecondCount() - StartTime)); // return(AmountTicks) ; // return((double)AmountTicks / (GetMicrosecondCount() - StartTime)); } void OnTick() { AmountTicks++; }
| Configuration (OnTick) | Durée (mcs) | Nombre de ticks | Performance (ticks/mcs) |
|---|---|---|---|
| EURUSD | 1079331 | 9 927 153 | 9,19 |
| GBPUSD | 1 229 032 | 11 309 740 | 9,20 |
| USDJPY | 1 307 322 | 11 986 756 | 9,16 |
| USDCHF | 1 121 541 | 10359511 | 9,23 |
| AUDUSD | 1 175 578 | 10758136 | 9,15 |
On constate clairement que les performances du Testeur, exprimées en nombre de ticks par unité de temps, ne dépendent pas du symbole (mode par pips).
Expert multisinaux.
#property tester_no_cache input group "Benchmark: https://www.mql5.com/ru/forum/282062/page49#comment_50801337" input int inRange = 0; #include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/fr/code/47647 const ulong StartTime = GetMicrosecondCount(); int AmountTicks = 0; double OnTester() { return((double)(GetMicrosecondCount() - StartTime)); // return(AmountTicks) ; // return((double)AmountTicks / (GetMicrosecondCount() - StartTime)); } // OnTick multi-caractères. void OnTickMulti( const string &Symb, const int &Index ) { AmountTicks++; }
| Configuration (OnTickMulti) | Durée (OnTickMulti) | Durée (OnTick) | Nombre de ticks | Performance (OnTickMulti) | Performance (OnTick) |
|---|---|---|---|---|---|
| EURUSD | 3455901 | 1 079 331 | 9 927 153 | 2,87 | 9,19 |
| EURUSD, GBPUSD | 6617085 | 2 308 363 | 21 236 893 | 3,20 | 9,19 |
| EURUSD, GBPUSD, USDJPY | 9188781 | 3615685 | 33 223 649 | 3,61 | 9,18 |
| EURUSD, GBPUSD, USDJPY, USDCHF | 11517804 | 4737226 | 43 583 160 | 3,78 | 9,20 |
| EURUSD, GBPUSD, USDJPY, USDCHF, AUDUSD | 16058223 | 5912804 | 54 341 296 | 3,38 | 9,19 |
La performance dépend peu du nombre de caractères, mais elle est trois fois inférieure.
Conclusion.
Si votre expert multidevises est constitué d’un mélange de sous-stratégies monodevises indépendantes, il sera (au moins) trois fois plus rapide d'optimiser chacune des sous-stratégies (puis de les regrouper via Validate en un seul passage) séparément, plutôt que de les optimiser toutes ensemble au sein d'un seul expert multidevises.
- www.mql5.com
// OnTick multi-caractères. void OnTickMulti( const string &Symb, const u int &Index )
Bonjour,
Il semblerait que, sur les dernières versions (5200+), le code ne se compile plus :
#include <fxsaber\OnTickMulti\OnTickMulti.mqh> // OnTick multicharactère. int TicksCounter[]; // Compteur du nombre de ticks reçus pour chaque caractère spécifié. void OnInit() { // Initialisation du compteur de ticks reçus. ArrayResize(TicksCounter, ArraySize(OnTickMulti.Symbols)); ArrayInitialize(TicksCounter, 0); } double OnTester() { // Nous affichons le nombre de ticks reçus pour chaque caractère spécifié. for (uint i = ArraySize(TicksCounter); (bool)i--;) Print(OnTickMulti.Symbols[i] + " - " + (string)TicksCounter[i] + " ticks."); ArrayPrint(OnTickMulti.Symbols); // Liste des caractères OnTickMulti. return(0); } // OnTick multicharactère. void OnTickMulti( const string &Symb, const uint &Index ) { TicksCounter[Index]++; // On a incrémenté le compteur des ticks reçus pour le caractère spécifié. }
La bibliothèque a été mise à jour pour prendre en charge les modifications apportées àMQL5_b5200+.
- 2025.07.31
- www.mql5.com
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation


OnTickMulti:
Multisymbol OnTick.
Author: fxsaber