Bibliotheken: Symbol - Seite 2

 
Stanislav Korotky:

Wir sollten etwas hinzufügen wie:

Ansonsten werden manchmal nur Eigenschaften benötigt und keine Balken.

Alle Methoden der Klasse sind öffentlich. Um also nur Eigenschaften zu klonen, rufen Sie CloneProperties() auf.

 

Die Bibliothek und das Anwendungsbeispiel wurden aktualisiert.

Пример

Wenn ein Backtest auf Kreuzen läuft, zieht der Tester nicht nur das Hauptsymbol, sondern auch ein Hilfssymbol, das die Umrechnung der Gewinnwährung des Hauptsymbols in die Kontowährung ermöglicht. Das Ziehen des Hilfssymbols, die Generierung seiner Ticks und die Synchronisierung mit dem Hauptsymbol beanspruchen im Einzellauf- und insbesondere im Optimierungsmodus wertvolle Rechenressourcen (und Zeit).


Eine solche Präzision ist jedoch fast immer unnötig. Deshalb möchte ich diese Besessenheit/Unvollkommenheit des MetaTrader 5-Testers umgehen. In MetaTrader 4 ist dies einfach möglich - es gibt eine Möglichkeit, die Kontowährung direkt im Tester zu ändern. MetaTrader 5 hat eine solche Möglichkeit nicht.

Das Demoskript zeigt eine Möglichkeit, diese Einschränkung des Testers zu umgehen - unnötige Berechnungen zu entfernen. Zu diesem Zweck wird eine Kopie des Symbols für den Backtest erstellt, aber die Währung des Gewinns/der Marge wird auf die Kontowährung gesetzt. Das heißt, die Handelsergebnisse müssen nicht umgerechnet werden. Und der Gewinn wird tatsächlich in Pips berechnet, was in manchen Situationen sehr deutlich sein kann.

// Erstellen Sie eine Kopie des Symbols, um den Tester zu beschleunigen
#property script_show_inputs

#include <Symbol.mqh>

void OnStart()
{
  const SYMBOL Symb("TESTER_" + _Symbol); // Erstellt ein Symbol

  if (Symb.IsExist()) // Wenn das Symbol erstellt wird
  {
    Symb = _Symbol; // Kopiert alle Eigenschaften und den Balkenverlauf (+ Tickverlauf, falls benutzerdefiniert) vom Hauptsymbol - Klonen

    // Die Währungen des Symbols zur Währung des Kontos machen
    Symb.SetProperty(SYMBOL_CURRENCY_PROFIT, AccountInfoString(ACCOUNT_CURRENCY));
    Symb.SetProperty(SYMBOL_CURRENCY_MARGIN, AccountInfoString(ACCOUNT_CURRENCY));

    if (Symb.On()) // Enthalten in der Marktbeobachtung
      ChartOpen(Symb.Name, PERIOD_CURRENT); // Öffnete eine neue Symboltabelle
  }
}


Ergebnis


Auf diese Weise wird eine kostenlose Beschleunigung des Testers/Optimierers erreicht.


ZЫ Ich habe es gründlich am EURGBP gemessen . Der Zeitgewinn beträgt ~2 mal. Die Trades sind vollständig aufeinander abgestimmt. In der Tat kostenlos!

 

Die folgende Bemerkung betrifft nicht nur die Bibliothek.


Wenn Sie einige Eigenschaften eines benutzerdefinierten Symbols ändern müssen, sollte dies in einigen Fällen VOR dem Import von Zitaten geschehen.

Um die Zuverlässigkeit des Ergebnisses zu gewährleisten, empfehle ich daher dringend, zuerst alle Eigenschaften des Symbols festzulegen und erst dann zu importieren.

Wenn Sie zum Beispiel SYMBOL_TRADE_TICK_VALUE und SYMBOL_TRADE_TICK_SIZE einstellen möchten, sollten Sie dies vor dem Importieren von Ticks/Balken tun.

 

Im MT5-Tester haben Limit-Orders in der Regel (z.B. im Forex-Bereich) eine positive Slippage, was zu einer Selbsttäuschung führt (manchmal sogar in Form von Tester-Grails auf echten Ticks!).



Es gibt jedoch eine Möglichkeit, diese Funktion des Testers zu umgehen. Im Folgenden finden Sie eine detaillierte Anleitung dazu.


1. Wenn das ursprüngliche Symbol (offener Chart) nicht benutzerdefiniert ist oder das Konto abgesichert ist, führen Sie dieses Skript auf dem Symbolchart aus

#include <Symbol.mqh>

void OnStart()
{
  const SYMBOL Symb(_Symbol + "_Custom"); // Erstellt ein Symbol

  if (Symb.IsExist()) // Wenn das Symbol erstellt wird
  {
    Symb = _Symbol;   // Kopieren Sie alle Eigenschaften und den Balkenverlauf (+ Tickverlauf, falls benutzerdefiniert) vom Hauptsymbol - Klonen

    if (Symb.On())    // Enthalten in der Marktbeobachtung
      ChartOpen(Symb.Name, PERIOD_CURRENT); // Öffnete eine neue Symboltabelle
  }
}


Sie erhalten dann dieses Bild



2. Wenn das Konto abgesichert ist (das Wort Hedge steht in der Titelleiste des Terminal-Fensters), wechseln Sie zu einem beliebigen Netting-Konto (z. B. MetaQuotes-Demo) und laden Sie das Terminal neu.

3. Führen Sie dieses Skript auf dem aktuellen Chart aus.

// Erstellung einer Kopie des Symbols, um den Tester zu beschleunigen, mit der Möglichkeit, den Slippage von Limit-Orders zu deaktivieren
#property script_show_inputs

#include <Symbol.mqh>

input bool OrderLimitSlippage = false;

void OnStart()
{
  const SYMBOL Symb("TESTER_" + _Symbol); // Erstellt ein Symbol

  if (Symb.IsExist()) // Wenn das Symbol erstellt wird
  {
    // https://www.mql5.com/ru/forum/212096/page2#comment_7017794
// Symbol = _Symbol; // Kopieren Sie alle Eigenschaften und den Balkenverlauf (+ Tickverlauf, falls benutzerdefiniert) vom Hauptsymbol - Klonen

    Symb.CloneProperties(); // Kopieren aller Eigenschaften aus dem Hauptsymbol

    // Die Währungen des Symbols zur Währung des Kontos machen
    Symb.SetProperty(SYMBOL_CURRENCY_PROFIT, AccountInfoString(ACCOUNT_CURRENCY));
    Symb.SetProperty(SYMBOL_CURRENCY_MARGIN, AccountInfoString(ACCOUNT_CURRENCY));
    Symb.SetProperty(SYMBOL_CURRENCY_BASE, AccountInfoString(ACCOUNT_CURRENCY));
    
    int Answer = IDNO;
    
    // Slippage von Limitaufträgen entfernen
    // https://www.mql5.com/ru/forum/212096/page2#comment_7018318
    if (!OrderLimitSlippage &&
        (((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE) != ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) ||
        ((Answer = MessageBox("You will need to change the account type to netting.\nDo you agree to disable limit order slips?", __FILE__, MB_YESNOCANCEL | MB_ICONQUESTION)) == IDYES)))
    {
      Symb.SetProperty(SYMBOL_TRADE_EXEMODE, SYMBOL_TRADE_EXECUTION_EXCHANGE);
      Symb.SetProperty(SYMBOL_TRADE_CALC_MODE, SYMBOL_CALC_MODE_EXCH_FUTURES);
      
      // Zur Berechnung des Gewinns
      Symb.SetProperty(SYMBOL_TRADE_TICK_VALUE, 1);
      Symb.SetProperty(SYMBOL_TRADE_TICK_SIZE, Symb.GetProperty(SYMBOL_POINT));
    }
    
    if ((Answer != IDCANCEL) && (Symb.CloneHistory() > 0) && Symb.On()) // Kopiert die Balkenhistorie (+ Tickhistorie, falls benutzerdefiniert) vom Hauptsymbol
      ChartOpen(Symb.Name, PERIOD_CURRENT); // Öffnete eine neue Symboltabelle 
  }
}



3. Wählen Sie das erhaltene benutzerdefinierte Symbol im Tester


Jetzt werden Limit-Orders nicht mehr rutschen!

 

Forum zum Thema Handel, automatische Handelssysteme und Testen von Handelsstrategien

Fehler, Bugs, Fragen

fxsaber, 2018.02.14 14:41 AM.

Hässlicher Bug nicht Terminal, sondern Plattform MT5
#include <MT4Orders.mqh> // https://www.mql5.com/de/code/16006

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnStart()
{
  OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, Bid);
  
// OrderSend(_Symbol, OP_BUYLIMIT, 1, Ask, 100, 0, 0);
}

Läuft auf MQ-Demo auf einige sich langsam bewegende Symbol. Zum Beispiel, EURHUF.

Das Skript öffnet eine BUY-Position mit TP = Bid. D.h. die Position sollte sofort geschlossen werden. Der TP wird aber erst beim nächsten Tick auf Erfüllung der Annahmebedingung geprüft!

Eine sofortige Schließung der Position erfolgt erst beim nächsten Tick. Und wenn der nächste Tick Bid < TP hat, bleibt TP ohne Akzeptanz.


Das Gleiche gilt für Limit-Orders (kommentierte Zeile). Im Tester ist die Situation ähnlich.

Auf das Hervorgehobene sollte hingewiesen werden, denn im vorhergehenden Beitrag gibt es dieses

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien.

Bibliotheken: Symbol

fxsaber, 2018.04.06 09:21 Uhr.

2. Wenn das Konto abgesichert ist (das Wort Hedge ist in der Titelleiste des Terminal-Fensters vorhanden), gehen Sie zu einem beliebigen Netting-Konto (z.B. MetaQuotes-Demo) und laden Sie das Terminal neu.

und nicht jeder wird bemerken, dass Limit-Orders zum aktuellen Kurs auf Börsensymbolen von Netting-Konten sofort (und im Tester) ausgeführt werden, ohne auf den nächsten Tick zu warten.


Beachten Sie, dass nicht nur das Börsensymbol wichtig ist, sondern auch das Netting-Konto. Sie können z.B. ein MOEX-Symbol auf einem Hedge-MQ-Demo nehmen, aber es wird nicht auf die gleiche Weise (und im Tester) ausgeführt wie auf demselben Netting-MQ-Demo.

Dies ist einer der Gründe, warum Backtests auf denselben völlig identischen MOEX-Symbolen je nach Kontotyp unterschiedlich ausfallen können.


ZЫ Ich spreche mit mir selbst....

 
fxsaber:

ZY Ich führe Selbstgespräche...

Nein, ich habe nur nichts hinzuzufügen.

Es ist schade, dass man mit Tamburinen tanzen muss, um die normale Auslösung von Befehlen zu realisieren.

 
Andrey Khatimlianskii:

Es ist schade, dass man mit Tamburinen tanzen muss, um das normale Auslösen von Befehlen zu realisieren.

Ich habe die Anweisungen geändert und die Tänze erheblich vereinfacht. Zum Beispiel wird beim Netting alles mit einem Klick erledigt - das Skript wird gestartet.

 

Ich habe einen einfachen Filter auf echte Ticks angewandt, der im leichtesten Fall > 90 % der Informationen herausfiltert. Je stärker der Filter, desto gröber das Backtest-Ergebnis.

Aber es war interessant, wie sich der schwächste Filter auf das Ergebnis und die Geschwindigkeit auswirkt.


Qualität.

War

final balance 10007242.00 EUR
TESTER_Censored,M1: 6589567 ticks, 60353 bars generated. Environment synchronized in 0:00:00.031. Test passed in 0:00:05.101 (including ticks preprocessing 0:00:00.874).
TESTER_Censored,M1: total time from login to stop testing 0:00:05.132 (including 0:00:00.031 for history data synchronization)
476 Mb memory used including 27 Mb of history data, 192 Mb of tick data


Wurde

final balance 10007246.00 EUR
FILTER_Censored,M1: 402622 ticks, 50887 bars generated. Environment synchronized in 0:00:00.030. Test passed in 0:00:00.516 (including ticks preprocessing 0:00:00.078).
FILTER_Censored,M1: total time from login to stop testing 0:00:00.546 (including 0:00:00.030 for history data synchronization)
314 Mb memory used including 27 Mb of history data, 64 Mb of tick data


Geschwindigkeit

Wurde

OnTesterInit
i = 0 Pass = 0 OnTester = 3.881 s.: Count = 6589567, 1697904.4 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 1 Pass = 1 OnTester = 3.893 s.: Count = 6589567, 1692670.7 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 2 Pass = 2 OnTester = 3.898 s.: Count = 6589567, 1690499.5 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 3 Pass = 3 OnTester = 3.842 s.: Count = 6589567, 1715139.8 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 4 Pass = 4 OnTester = 3.912 s.: Count = 6589567, 1684449.6 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
iMin = 3 Results[iMin] = 3.842 s.
iMax = 4 Results[iMax] = 3.912 s.
Amount = 5 Mean = 3.885 s. - 84.80%
OnTesterDeinit


War

OnTesterInit
i = 0 Pass = 0 OnTester = 0.264 s.: Count = 402622, 1525083.3 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 1 Pass = 1 OnTester = 0.264 s.: Count = 402622, 1525083.3 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 2 Pass = 2 OnTester = 0.264 s.: Count = 402622, 1525083.3 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 3 Pass = 3 OnTester = 0.266 s.: Count = 402622, 1513616.5 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 4 Pass = 4 OnTester = 0.306 s.: Count = 402622, 1315758.2 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
iMin = 0 Results[iMin] = 0.264 s.
iMax = 4 Results[iMax] = 0.306 s.
Amount = 5 Mean = 0.273 s. - 29.28%
OnTesterDeinit


Ergebnis

Nach realen Ticks verringerte sich die Anzahl der Ticks um das 16-fache (der leichteste Filter), die Geschwindigkeit der Optimierung erhöhte sich um das 14-fache, die Qualität litt überhaupt nicht (die Analyse, die hier nicht berücksichtigt wurde). Natürlich ist dies nur möglich, wenn der TS auf eine bestimmte Weise geschrieben wird. Vor allem, wenn die Balkenanalyse fehlt.

Die frühere kostenlose Universalbeschleunigung brachte nur eine zweifache Steigerung. Die aktuelle ist ebenfalls kostenlos (die Qualität leidet nicht), aber weniger universell. Der Gewinn liegt jedoch um mehr als eine Größenordnung höher. Jetzt optimiere ich TC nur noch auf diese Weise. Kein Fehler.


SZY

Gleichzeitig eine kurze Überprüfung dieser Implementierung (nur Bar Spread anders berechnet).

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien.

Skripte: ThirdPartyTicks

Automated-Trading, 2018.03.16 09:35 Uhr.

Баровая история создается с учетом минимальных потерь качества при переходе от режима тестирования "Каждый тик на основе реальных тиков" к "Только цены открытия" - ТС на лимитных ордерах;

Es werden zwei Modi verglichen: "Alle Ticks" und "OHLC M1".


Alle Ticks

final balance 10006150.00 EUR
TESTER4_Censored,M1: 6576734 ticks, 60353 bars generated. Test passed in 0:00:04.587 (including ticks preprocessing 0:00:00.343).
394 Mb memory used including 27 Mb of history data, 128 Mb of tick data


OHLC M1

final balance 10006119.00 EUR
TESTER_Censored,M1: 240366 ticks, 60353 bars generated. Test passed in 0:00:00.359 (including ticks preprocessing 0:00:00.031).
306 Mb memory used including 27 Mb of history data, 64 Mb of tick data


Die Backtest-Qualität ist gleich, die Performance der zweiten Variante in einem Durchgang ist 12-mal besser.

 

Müssen diese Skripte von einem Nicht-Programmierer in ein Expert Advisor-Programm geschrieben werden?

Es ist sehr verlockend, die Optimierung um den Faktor 12 zu beschleunigen.

Gibt es eine solche Beschleunigung bei der Optimierung durch Eröffnungspunkte?

 
Aleksey Panfilov:

Müssen diese Skripte von einem Nicht-Programmierer in ein EA-Programm geschrieben werden?

Es ist sehr verlockend, die Optimierung um den Faktor 12 zu beschleunigen.

Gibt es eine solche Beschleunigung bei der Optimierung durch Eröffnungspunkte?

Leider ist es sehr schwierig, alle Aspekte dieses Prozesses zu erklären. Wahrscheinlich bräuchte man dafür einen ganzen Artikel. Daher wird es nicht möglich sein, ihn klar und kurz zu erklären.