- www.mql5.com
if (prev_calculated) EventChartCustom(Chart, 0, Index, 0, NULL);Es kann vorkommen, dass Ticks übersprungen werden, wenn das Ereignis nicht in die Warteschlange gestellt wird. Das kommt vor (vor allem auf einem VPS oder einem langsamen Computer).
Leider lassen selbst einfache Expert Advisors, die nur über die Funktion „OnTick“ verfügen, Ticks aus. Bei handelsaktiven Expert Advisors werden CopyTicks-Funktionen und andere Kniffe eingesetzt, um sicherzustellen, dass keine Ticks ausgelassen werden.
Diese Bibliothek lässt garantiert keine Ticks aus – allerdings nur im Tester. Alles läuft genau wie bei OnTick.
/* // https://www.mql5.com/ru/blogs/post/755348 #define VIRTUAL_TESTER_MULTI // Start in der virtuellen Handelsumgebung OnTickMulti #define VIRTUAL_LIMITS_TP_SLIPPAGE // Limit-Orders und TP werden zum ersten akzeptierten Preis ausgeführt – positives Slippage #define VIRTUAL_CLOSEALL_BYEND // Schließt alle Orders am Ende des Tests zwangsweise // #define VIRTUAL_ALTERNATIVE // Alternative Abrechnungsgeschwindigkeit */ #include <MT4Orders.mqh> // https://www.mql5.com/de/code/16006 #include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/de/code/47647 /* #define REPORT_TESTER // Im Tester werden Berichte automatisch gespeichert #define REPORT_BROWSER // Bericht erstellen und Browser starten – erfordert DLL-Berechtigung. #include <Report.mqh> // https://www.mql5.com/de/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 mit mehreren Zeichen. 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); } }
Einstellungen des Testers.
Beschleunigung.
Man kann den Code beschleunigen, indem man am Anfang einige Zeilen auskommentiert.
| Konfiguration | Ergebnis |
|---|---|
| Ohne Virtual.mqh. | kürzester Durchlauf 0:00:13,184, längster Durchlauf 0:00:15,031, durchschnittlicher Durchlauf 0:00:13,633 |
| Mit Virtual.mqh, inVirtualTester = false. | kürzester Durchlauf 0:00:14,735, längster Durchlauf 0:00:16,384, durchschnittlicher Durchlauf 0:00:15,081 |
| Mit Virtual.mqh, inVirtualTester = true. | kürzester Durchlauf 0:00:05,872, längster Durchlauf 0:00:05,964, durchschnittlicher Durchlauf 0:00:05,919 |
| Mit Virtual.mqh, inVirtualTester = true + VIRTUAL_ALTERNATIVE. | kürzester Durchlauf 0:00:06,172, längster Durchlauf 0:00:07,791, durchschnittlicher Durchlauf 0:00:06,524 |
Der Expert Advisor ist äußerst einfach aufgebaut (0–2 offene Positionen pro Wertpapier mit festen SL/TP, ohne Pending Orders), weshalb in dieser Variante lediglich eine 2,5-fache Beschleunigung erreicht werden kann.
TickValue+Swap+Commission.
Die oben genannten Tests wurden im Pip-Modus durchgeführt (siehe Screenshot der Einstellungen), um den TickValue nicht bei jedem Tick neu berechnen zu müssen und dafür andere Symbole einzubinden. In diesem Modus sind die Ergebnisse identisch.
Wenn eine maximale Beschleunigung mit vollem Umfang erforderlich ist, sollte diese Lösung verwendet werden.
- 2023.12.25
- www.mql5.com
Forum zu Trading, automatisierten Handelssystemen und dem Testen von Handelsstrategien
fxsaber, 18.03.2024, 18:36
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); } }
| Konfiguration | Ergebnis |
|---|---|
| Ohne Virtual.mqh. | kürzester Durchlauf 0:00:13,184, längster Durchlauf 0:00:15,031, durchschnittlicher Durchlauf 0:00:13,633 |
Oben habe ich im Code eine einfache Methode zur Beschleunigung eines Multi-Währungs-Expert-Advisors ohne jegliche Virtual-Bibliotheken hervorgehoben.
| Konfiguration | Ergebnis |
|---|---|
| Ohne Virtual.mqh +MagicNumberOrderSymbol | kürzester Durchlauf 0:00:08,608, längster Durchlauf 0:00:10,236, durchschnittlicher Durchlauf 0:00:08,942 |
Eine kostenlose Beschleunigung um das 1,5-Fache!
Ich habe die Verlangsamung des Testers beim Wechsel vom Ein-Zeichen-Modus zum Mehrzeichen-Modus überprüft. Das war nicht ganz perfekt – der Berater ist nur ein Platzhalter.
Einziffern-Expert Advisor.
#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++; }
| Konfiguration (OnTick) | TimeLength (mcs) | Anzahl der Ticks | Leistung (Ticks/mcs) |
|---|---|---|---|
| EURUSD | 1079331 | 9927153 | 9,19 |
| GBPUSD | 1.229.032 | 11.309.740 | 9,20 |
| USDJPY | 1.307.322 | 11986756 | 9,16 |
| USDCHF | 1.121.541 | 10359511 | 9,23 |
| AUDUSD | 1.175.578 | 10758136 | 9,15 |
Es ist deutlich zu erkennen, dass die Leistung des Testers, gemessen an der Anzahl der Ticks pro Zeiteinheit, nicht vom Symbol abhängt (Pips-Modus).
Multi-Symbol-Expert Advisor.
#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/de/code/47647 const ulong StartTime = GetMicrosecondCount(); int AmountTicks = 0; double OnTester() { return((double)(GetMicrosecondCount() - StartTime)); // return(AmountTicks); // return((double)AmountTicks / (GetMicrosecondCount() - StartTime)); } // OnTick mit mehreren Zeichen. void OnTickMulti( const string &Symb, const int &Index ) { AmountTicks++; }
| Konfiguration (OnTickMulti) | TimeLength (OnTickMulti) | TimeLength (OnTick) | Anzahl der Ticks | Performance (OnTickMulti) | Performance (OnTick) |
|---|---|---|---|---|---|
| EURUSD | 3455901 | 1.079.331 | 9.927.153 | 2,87 | 9,19 |
| EUR/USD, GBP/USD | 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 |
Die Leistung hängt nur geringfügig von der Anzahl der Zeichen ab, ist jedoch dreimal niedriger.
Fazit:
Wenn Ihr Multi-Währungs-Expert Advisor aus einer Mischung unabhängiger Single-Währungs-Sub-TS besteht, ist es (mindestens) dreimal schneller, jeden der Sub-TS einzeln zu optimieren (und anschließend über Validate in einem Durchgang zusammenzufassen), als alle gemeinsam in einem Multiwährungs-Expert Advisor zu optimieren.
- www.mql5.com
// OnTick mit mehreren Zeichen. void OnTickMulti( const string &Symb, const u int &Index )
Hallo,
Es sieht so aus, als würde der Code bei den neuesten Builds (5200+) nicht mehr kompiliert werden:
#include <fxsaber\OnTickMulti\OnTickMulti.mqh> // OnTick mit mehreren Zeichen. int TicksCounter[]; // Zähler für die Anzahl der eingegangenen Ticks jedes angegebenen Zeichens. void OnInit() { // Wir initialisieren den Zähler für die eingegangenen Ticks. ArrayResize(TicksCounter, ArraySize(OnTickMulti.Symbols)); ArrayInitialize(TicksCounter, 0); } double OnTester() { // Wir geben die Anzahl der eingegangenen Ticks für jedes angegebene Symbol aus. for (uint i = ArraySize(TicksCounter); (bool)i--;) Print(OnTickMulti.Symbols[i] + " - " + (string)TicksCounter[i] + " ticks."); ArrayPrint(OnTickMulti.Symbols); // Liste der OnTickMulti-Zeichen. return(0); } // OnTick mit mehreren Zeichen. void OnTickMulti( const string &Symb, const uint &Index ) { TicksCounter[Index]++; // Der Zähler für die eingegangenen Ticks für das angegebene Symbol wurde erhöht. }
Es sieht so aus, als würde der Code bei den neuesten Builds (5200+) nicht mehr kompiliert werden
DieBibliothek wurde an die Änderungen inMQL5_b5200+angepasst.
- 2025.07.31
- www.mql5.com
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.


OnTickMulti:
Multisymbol OnTick.
Author: fxsaber