Alle Statistiken, die im Single Run Report enthalten sind, sind verfügbar. Zuvor war es unmöglich, viele dieser Daten zu erhalten, selbst wenn Sie die Quelle des Expert Advisors haben.
double ghpr; // Geometrisches Mittel der Transaktion double ghprpercent; // Geometrisches Mittel der Transaktion in Prozent double ahpr; // arithmetisches Mittel der Transaktion double ahprpercent; // Arithmetisches Mittel der Transaktionen in Prozent double zscore; // Serienprüfung double zscorepercent; // Serientest in Prozent double lrcorr; // Korrelationskoeffizient der linearen Regression double lrstderror; // Standardfehler der Gleichgewichtsabweichung aus linearer Regression double corr_prf_mfe; // Korrelation zwischen mfe und Gewinn double corr_prf_mae; // Korrelation zwischen Mae und Gewinn double corr_mfe_mae; // Korrelation zwischen mae und mfe double mfe_a; // Korrelation zwischen Bruttoinlandsprodukt und Gewinn, Koeffizient der linearen Regressionslinie double mfe_b; // Korrelation zwischen Bruttoinlandsprodukt und Gewinn, Koeffizient der linearen Regressionslinie double mae_a; // Korrelation zwischen Mae und Gewinn, Koeffizient für lineare Regressionslinie double mae_b; // Korrelation zwischen Mae und Gewinn, Koeffizient für lineare Regressionslinie UINT in_per_hours[24]; // Verteilung der Eingänge nach Stunden UINT in_per_week_days[7]; // Verteilung der Eingänge nach Wochentagen UINT in_per_months[12]; // Verteilung der Eingänge nach Monaten double out_per_hours[24][2]; // Verteilung der Eingänge nach Stunden double out_per_week_days[7][2]; // Verteilung der Eingänge nach Wochentagen double out_per_months[12][2]; // Verteilung der Eingänge nach Monaten INT64 holding_time_min; // minimale Positionshaltezeit INT64 holding_time_max; // Maximale Haltezeit der Position INT64 holding_time_avr; // Durchschnittliche Positionshaltezeit
In der aktuellen Version des tst-Formats fehlen die folgenden Angaben
- Zeit in Millisekunden.
- PositionID.
- MagicNumber.
Reproduktion mehrerer Bugs. Führen Sie den Expert Advisor im Tester auf einem Hedge-Konto aus.
#include <MT4Orders.mqh> // https://www.mql5.com/de/code/16006 #define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK) #define PAUSE 100000 void OnTick() { static bool FirstRun = true; if (FirstRun) { OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0); Sleep(PAUSE); OrderSend(_Symbol, OP_BUY, 2, Ask, 0, 0, 0); Sleep(PAUSE); if (OrderSelect(0, SELECT_BY_POS)) OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0); Sleep(PAUSE * 2); if (OrderSelect(0, SELECT_BY_POS)) OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0); Sleep(PAUSE * 2); TesterWithdrawal(100); FirstRun = false; } } void OnDeinit( const int ) { const int Total = OrdersHistoryTotal(); for (int i = 0; i < Total; i++) if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { OrderPrint(); Print(OrderTicketID()); // MT5-PositionID } }
Wir erhalten dies
2020.01.08 23:59:58 #1 2020.01.01 00:00:00 balance 0.00 0.00000 0.00000 0.00000 2020.01.01 00:00:00 0.00000 0.00 0.00 100000.00 0 2020.01.08 23:59:58 0 2020.01.08 23:59:58 #4 2020.01.02 06:00:00 buy 1.00 EURUSD 1.12137 0.00000 0.00000 2020.01.02 06:03:20 1.12132 -3.56 0.00 -4.46 0 2020.01.08 23:59:58 2 2020.01.08 23:59:58 #5 2020.01.02 06:01:40 buy 2.00 EURUSD 1.12137 0.00000 0.00000 2020.01.02 06:06:40 1.12129 -7.14 0.00 -14.27 0 2020.01.08 23:59:58 3 2020.01.08 23:59:58 #6 2020.01.02 06:10:00 balance 0.00 0.00000 0.00000 0.00000 2020.01.02 06:10:00 0.00000 0.00 0.00 -100.00 withdrawal 0 2020.01.08 23:59:58 0
Als nächstes lesen wir die entsprechende tst-Datei mit dem Skript.
#include <fxsaber\SingleTesterCache\SingleTesterCache.mqh> // https://www.mql5.com/de/code/27611 #include <fxsaber\MultiTester\MTTester.mqh> // https://www.mql5.com/de/code/26132 void OnStart() { uchar Bytes2[]; if (MTTESTER::GetLastTstCache(Bytes2) != -1) // Wenn es möglich wäre, den letzten Cache-Datensatz eines einzelnen Laufs zu lesen { const SINGLETESTERCACHE SingleTesterCache(Bytes2); // Fahren Sie es in das entsprechende Objekt. for (int i = 0; i < ArraySize(SingleTesterCache.Positions); i++) Print(SingleTesterCache.Positions[i].ToString()); } }
Es werden Daten zu Positionen angezeigt
id = 0 mfe = 0.0 mae = -8.029999999999999 profit = -4.46 lifetime = 00:03:20 id = 0 mfe = 0.0 mae = -21.4 profit = -14.27 lifetime = 00:05:00 id = 0 mfe = 0.0 mae = 0.0 profit = 0.0 lifetime = 00:00:00
Wenn wir alles in diesem Beitrag vergleichen, werden die folgenden Bugs formuliert.
- Null id's anstelle der korrekten id's.
- Kommission und Swap werden bei der Berechnung des Gewinns nicht berücksichtigt.
- Withdrawal-Trade wird fälschlicherweise in die Anzahl der geschlossenen Handelspositionen einbezogen.
Anstelle von set-Dateien verwende ich jetzt tst-Dateien. Man kann sehr schnell zwischen ihnen wechseln und hat nicht nur Eingabeparameter, sondern auch vollständige Backtests.
Es ist schade, dass es nicht möglich ist, verschiedene TS zu einem Portfolio zu kombinieren, weil es in tst keine Millisekunden-Daten gibt.
Ich hoffe, dass die Entwickler damit beginnen, die vorhandenen Felder voll auszunutzen.
INT64 TradeDeal::time_create; // Zeitpunkt der Erstellung des Datensatzes INT64 TradeOrder::time_setup; // Zeitpunkt des Auftragseingangs vom Kunden beim System INT64 TradeOrder::time_done; // Zeitpunkt der Stornierung der Bestellung
indem sie den Zeitwert in Millisekunden anstelle von Sekunden schreiben.
Im Allgemeinen, in der Praxis zu demonstrieren, alle die Kühle der Verwendung von tst nicht geben sehr kleine Mängel der tst. Das sollte korrigiert werden.
// Interaktives Gleichgewichtsdiagramm in einem Durchgang. #include <fxsaber\SingleTesterCache\SingleTesterCache.mqh> // https://www.mql5.com/de/code/27611 #include <fxsaber\MultiTester\MTTester.mqh> // https://www.mql5.com/de/code/26132 #include <..\Files\Graph.mqh> // https://www.mql5.com/de/code/18801 #import "shell32.dll" int ShellExecuteW( int, string, string, string, string, int ); #import #define BASEPATH (::TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Files\\") bool CreateBalanceData( const SINGLETESTERCACHE &SingleTesterCache, const string FileName = "exdat.txt" ) { const int handle = FileOpen(FileName, FILE_WRITE | FILE_TXT | FILE_ANSI); const bool Res = (handle != INVALID_HANDLE); if (Res) { FileWriteString(handle, "var dat1=[\n"); for (uint i = 0; i < SingleTesterCache.Header.equities_total; i++) FileWriteString(handle, "[" + (string)((long)SingleTesterCache.TradeState[i].time * 1000) + "," + ::DoubleToString(SingleTesterCache.TradeState[i].balance, 2) + "],\n"); FileWriteString(handle, "];\n"); FileWriteString(handle, "var T1=dat1[0][0];\n"); FileWriteString(handle, "var T2=dat1[dat1.length-1][0];\n"); FileWriteString(handle, "var nTrades=dat1.length;\n"); FileWriteString(handle, "var Balance=" + ::DoubleToString(SingleTesterCache.TradeState[SingleTesterCache.Header.equities_total - 1].balance, 2) + ";\n"); FileWriteString(handle, "var Currency=\"" + (SingleTesterCache.Header.trade_pips ? "Pips" : SingleTesterCache.Header.trade_currency[]) + "\";\n"); FileClose(handle); } return(Res); } void OnStart() { uchar Bytes2[]; if (MTTESTER::GetLastTstCache(Bytes2) != -1) // Wenn es möglich wäre, den letzten Cache-Datensatz eines einzelnen Laufs zu lesen { const SINGLETESTERCACHE SingleTesterCache(Bytes2); // Fahren Sie es in das entsprechende Objekt. const string FileName = "Report.htm"; uchar Array[]; if ((StringToCharArray(StrMQH, Array) > 0) && FileSave(FileName, Array) && CreateBalanceData(SingleTesterCache)) ShellExecuteW(0, "Open", BASEPATH + FileName, NULL, NULL, 3); } }
Wenn wir ersetzen
TradeState[i].balance -> TradeState[i].equity
ist es ein Gleichheitsdiagramm.
Das Volumen der Trades/Orders wird in tst falsch geschrieben. Es wird immer so berechnet, als ob SYMBOL_TRADE_CONTRACT_SIZE = 100 000.
Wenn ein anderer Wert eingestellt wird, hat dies keine Auswirkungen auf den Volumenwert in tst.
in der Praxis zu demonstrieren, ist die ganze Coolness der Verwendung von tst in der Praxis überhaupt nicht durch kleine Mängel von tst gegeben. Es sollte korrigiert werden.
Dieerste Schwalbe.
- www.mql5.com
- 2020.01.16
- www.mql5.com
Dort wird geantwortet.
Ich weiß nicht, wie das in Blogs abläuft. Wird das Erscheinen eines neuen Kommentars (wenn es sich nicht um eine Antwort handelt) irgendwie signalisiert? Oder ist es besser, in einem der Forumsthemen zu posten, wo neue Kommentare sichtbar sind?
Warum haben sie es nicht in der KB veröffentlicht? Das wäre doch viel praktischer.
Wo sollte man also posten, um eine schnelle Antwort zu erhalten?
- 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.


SingleTesterCache:
Daten des Prüfers in einem Durchgang.
Author: fxsaber