Diskussion zum Artikel "Entwicklung eines Expertenberaters für mehrere Währungen (Teil 2): Übergang zu virtuellen Positionen von Handelsstrategien" - Seite 5

 
mytarmailS #:
Es ist keine Tatsache, dass die Kompliziertheit des Modells auf dem Markt besser funktioniert als ein Korb mit einfachen TS
Nun, es ist nicht notwendig, jeden TS in den Trog zu trinken, sondern einfach neue TS nach mehreren Durchläufen des Optimierers hinzuzufügen.
 
Maxim Dmitrievsky in einem Korb zusammenfassen (bagging ), sondern boosten. Dabei wird zunächst eine Strategie optimiert, dann werden ihre Signale als Parameter für die zweite Strategie eingesetzt, die zweite Strategie wird optimiert usw.

Mir scheint, dass die Umsetzung des Hervorgehobenen eine nicht ganz triviale Aufgabe ist. Normalerweise werden die Strategieparameter zu Beginn festgelegt, und die Eröffnungs-/Schließungssignale werden von einem Algorithmus bestimmt, während die Strategie läuft. Wenn wir die Historie der Eröffnungen in einer einheitlichen Form speichern, dann muss das alles in den Input der zweiten Strategie eingespeist werden.... Ist das so? Wenn wir diese Informationen in Form eines Algorithmus (Funktion) und seiner festen Parameter bereitstellen, wird sich dann nicht herausstellen, dass wir zum gleichen Bagging gekommen sind, aber mit einer Hintertür?

 

Vielen Dank, ich habe es mit Interesse gelesen. Ich möchte etwas ähnliches machen, nur mit mehr Automatisierung, wofür ich vorhabe, Ihre Bibliotheken für die Arbeit mit *.opt- und *.tst-Dateien des Testers gnadenlos in Betrieb zu nehmen.

 
Yuriy Bykov #:

Es scheint mir, dass die Implementierung der hervorgehobenen eine sehr nicht-triviale Aufgabe ist. Normalerweise werden die Strategieparameter beim Start festgelegt, und die Eröffnungs-/Schließungssignale werden von einem Algorithmus bestimmt, während die Strategie läuft. Wenn wir die Historie der Eröffnungen in einer einheitlichen Form speichern, dann müssen alle diese Daten in den Eingang der zweiten Strategie .... eingespeist werden. Ist das so? Wenn wir diese Informationen in Form eines Algorithmus (Funktion) und seiner festen Parameter bereitstellen, wird sich dann nicht herausstellen, dass wir zum gleichen Bagging gekommen sind, aber mit einer Hintertür?

Ich habe nicht darüber nachgedacht, wie man das mit dem Optimierer machen kann. Nein, es sollte sich herausstellen, dass jede nächste Strategie die vorherige verbessert, d.h. auf ihr aufbaut. Wie man sich das genau vorstellt, ist eine Frage der Zeit. Sie können einfach im Internet nachschlagen, wie Boosted Trees funktionieren, und sie als Grundlage für Ihren Entwurf verwenden. Es mag eine Menge Nuancen geben, ja. Aber ich werde es nicht selbst tun, denn all dies ist bereits in den MO-Algorithmen enthalten. Und es ist kein Allheilmittel, aber es kann besser sein als ein TC-Portfolio in Bezug auf seine Eigenschaften.

 
Maxim Dmitrievsky #:

Ich hatte nicht darüber nachgedacht, wie man das über den Optimierer machen kann.

Dies ist eine Routine, die vollständig automatisiert werden kann, indem man den entsprechenden mqh mit mq5 verbindet.


Der Algorithmus ist wie folgt.

  1. Der Ordner enthält frühere Durchläufe (wenn es keine Durchläufe gab - leer) in Form von Dateien.
  2. Eine neue Optimierung wird gestartet: der TS selbst wird gehandelt + der Trade von Punkt 1 wird hinzugefügt. In diesem Fall wird MM gleichmäßig zwischen P.1 und TS verteilt.
  3. Der beste Durchgang (OnTester jeglicher Art) der Optimierung wird in Punkt 1 festgehalten.
  4. In P.2. so oft, wie der TS im Portfolio will.

Man kann also mischen, was man will. Es ist offensichtlich, dass selbst bei einer vollständigen Suche das Endergebnis von der Reihenfolge abhängt, in der die TS gestartet werden.

Es ist auch klar, dass selbst bei der SB mit jedem Durchgang eine Verbesserung der Indikatoren eintritt, aber es wird eine Anpassung sein.

 
Yuriy Bykov #:

Vielen Dank, ich habe mir den Code angesehen. Ich werde mir die Übergabe von Eingabeparametern später ansehen. Wenn es nicht klappt, diesen Ansatz vollständig zu übernehmen, werden einige Punkte wahrscheinlich sehr nützlich sein.

Ich habe die aktuellen Ergebnisse meiner Arbeit mit Eingaben (im Anhang) wieder auf den Code aus diesem Artikel angewendet.

Hier ist ein Beispiel dafür, was SimpleVolumesExpertSingle.mq5 geworden ist.

#define  INPUT_STRUCT_ADDON
#include "Advisor.mqh"
#include "SimpleVolumesStrategy.mqh"
#include "VolumeReceiver.mqh"

input string      symbol_              = "EURGBP";    // Handelsinstrument (Symbol)
input group "=== Beraterparameter".
input ulong       magic_              = 27181; // Magie

CAdvisor     *expert;         // Zeiger auf das Expertenobjekt

//+------------------------------------------------------------------+
//| Experteninitialisierungsfunktion|
//+------------------------------------------------------------------+
int OnInit() {
   expert = new CAdvisor(new CVolumeReceiver(magic_));

   // Hinzufügen einer Instanz der Strategie
   expert.Add(new CSimpleVolumesStrategy( symbol_, inStrategyInput + inSimpleVolumesStrategyInput));

   return(INIT_SUCCEEDED);
}


Es ist mir gelungen, eine einmalige Verschreibung von Eingaben(SimpleVolumesStrategyInput.mqh) im Code zu erreichen.

// https://www.mql5.com/de/code/47932
// Verwenden Sie diese Zeichenfolge, um alle Eingaben zu finden mqh.
// #include <fxsaber\Input_Struct\Input_Struct.mqh> // Original

#define  TYPENAME_INPUT SimpleVolumesStrategyInput

#define  MACROS_MULTI                    \
  MACROS(signalPeriod, int, 13)         \ // Anzahl der Kerzen für die Volumenmittelung
  MACROS(signalDeviation, double, 0.3)  \ // Relative Abweichung vom Durchschnitt bei der Eröffnung des ersten Auftrags
  MACROS(signaAddlDeviation, double, 1) \ // Relative Abweichung vom Durchschnitt für die Eröffnung des zweiten und der folgenden Aufträge
  MACROS(openDistance, int, 0)          \ // Abstand vom Preis zum schwebenden Auftrag
  MACROS(stopLevel, double, 10500)      \ // Stop Loss (in Punkten)
  MACROS(takeLevel, double, 465)        \ // Gewinnmitnahme (in Pips)
  MACROS(ordersExpiration, int, 1000)   \ // Verfallszeit der schwebenden Aufträge (in Minuten)
  MACROS(maxCountOfOrders, int, 3)        // Max. Anzahl der gleichzeitig geöffneten Aufträge

Dateien:
 
fxsaber #:

Ich habe die aktuellen Ergebnisse meiner Arbeit mit Eingaben (im Anhang) erneut auf den Code aus diesem Artikel angewandt.

Ein Beispiel dafür, was SimpleVolumesExpertSingle.mq5 geworden ist.


Es ist mir gelungen, eine einmalige Verschreibung von Eingaben(SimpleVolumesStrategyInput.mqh) im Code zu erreichen.

Es schien mir irgendwie spürbar einfacher als die vorherige Variante. Obwohl, vielleicht ist es einfach so, dass wenn man sich den Code von jemand anderem noch einmal anschaut, er jedes Mal klarer und einfacher wird. Ich danke Ihnen sehr! Beim Studieren ist mir eine Frage aufgefallen: Kann man den Code, der nach "// Copy-Paste update from here:" kommt, nicht in eine Include-Datei packen und anhängen, anstatt ihn einzufügen? Es ist nicht bequem, gerade jetzt zu experimentieren, also dachte ich, ich frage mal.

Im dritten Artikel bin ich noch nicht zu den Eingabeparametern gekommen :(. Aber das wird sicher noch kommen.

 
Yuriy Bykov #:

Während des Studiums stellte sich mir die Frage, ob es möglich ist, den Code, der nach "// Copy-Paste update from here:" kommt, in einer Include-Datei zu platzieren und ihn einzufügen, anstatt ihn einzufügen? Es ist nicht bequem, gerade jetzt zu experimentieren, so dass ich beschlossen, zu fragen.

Leider kann man das nicht, weil #include in derselben Datei nur einmal vorkommt - beim ersten Mal. Danach wird es ignoriert.

Das ist einer der Gründe, warum Sie hier eine völlig identische Datei mit einem anderen Namen erstellen mussten.


Aber im Allgemeinen ist die Copy-Paste-Option nur ein paar Klicks entfernt. Das Verständnis des Codes ist nicht erforderlich.

PriceChannel
PriceChannel
  • www.mql5.com
Ценовой канал произвольной длительности (таймфрейм) бара.
 
Yuriy Bykov #:

Im dritten Artikel haben die Eingabeparameter noch nicht die Eingabeparameter erreicht :(. Aber das wird sicher noch kommen.

Deine Architektur ist etwas anders als meine, deshalb habe ich INPUT_STRUCT nicht mit vielen Dingen versehen, die in diesem Projekt nützlich wären.

Es ist gut, dass du es nicht veröffentlicht hast, denn ich habe es noch einmal überarbeitet - in die prägnanteste und praktischste Version (es scheint die endgültige zu sein).

Ich habe Gruppen, String-Eingaben und einige andere kleine Dinge für die Zukunft hinzugefügt.

#define  TYPENAME_INPUT StrategyInput

#define  MACROS_MULTI                           \
  INPUT(symbol, string, "EURGBP")              \ // Handelsinstrument (Symbol)
  INPUT(timeframe, ENUM_TIMEFRAMES, PERIOD_H1) \ // Diagrammzeitraum (Zeitrahmen)
  GROUP("=== Kapitalverwaltungsoptionen") \
  INPUT(fixedLot, double, 0.01)                  // Größe der offenen Positionen (fest)
#define  TYPENAME_INPUT SimpleVolumesStrategyInput

#define  MACROS_MULTI                           \
  GROUP("=== Parameter des Eröffnungssignals")   \
  INPUT(signalPeriod, int, 13)                 \ // Anzahl der Kerzen für die Volumenmittelung
  INPUT(signalDeviation, double, 0.3)          \ // Relative Abweichung vom Durchschnitt bei der Eröffnung des ersten Auftrags
  INPUT(signaAddlDeviation, double, 1)         \ // Relative Abweichung vom Durchschnitt für die Eröffnung des zweiten und der folgenden Aufträge
  GROUP("=== Ausstehende Auftragsparameter.")   \
  INPUT(openDistance, int, 0)                  \ // Abstand vom Preis zum schwebenden Auftrag
  INPUT(stopLevel, double, 10500)              \ // Stop Loss (in Punkten)
  INPUT(takeLevel, double, 465)                \ // Gewinnmitnahme (in Pips)
  INPUT(ordersExpiration, int, 1000)           \ // Verfallszeit der schwebenden Aufträge (in Minuten)
  GROUP("=== Kapitalverwaltungsoptionen") \
  INPUT(maxCountOfOrders, int, 3)                // Max. Anzahl der gleichzeitig geöffneten Aufträge


Teile des Anwendungscodes, um zu demonstrieren, wie er verwendet wird.

#define  INPUT_STRUCT_ADDON
#include "Advisor.mqh"
#include "SimpleVolumesStrategy.mqh"
#include "VolumeReceiver.mqh"

input group "=== Parameter des Beraters".
input ulong       magic_              = 27181; // Magie

CAdvisor     *expert;         // Zeiger auf das Expertenobjekt

//+------------------------------------------------------------------+
//| Experteninitialisierungsfunktion|
//+------------------------------------------------------------------+
int OnInit() {
   expert = new CAdvisor(new CVolumeReceiver(magic_));

   // Hinzufügen einer Instanz der Strategie
   expert.Add(new CSimpleVolumesStrategy(inStrategyInput + inSimpleVolumesStrategyInput));

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Konstruktor|
//+------------------------------------------------------------------+
CSimpleVolumesStrategy::CSimpleVolumesStrategy( const string sInputs ) : CStrategy(sInputs)
{
   this.Input = sInputs;

   ArrayResize(m_orders, this.Input.maxCountOfOrders);

   // Laden Sie den Indikator, um Tick-Volumen zu erhalten
   iVolumesHandle = iVolumes(this.InputStrategy.symbol, this.InputStrategy.timeframe, VOLUME_TICK);

// Einstellen der Größe des Array-Empfängers von Tick-Volumes und der erforderlichen Adressierung
   ArrayResize(volumes, this.Input.signalPeriod);
   ArraySetAsSeries(volumes, true);
}
//+------------------------------------------------------------------+
//|| Konstruktor|
//+------------------------------------------------------------------+
CStrategy::CStrategy( const string sInputs ) : m_isChanged(false)
{
  this.InputStrategy = sInputs;
}
//+------------------------------------------------------------------+
//| Experteninitialisierungsfunktion|
//+------------------------------------------------------------------+
int OnInit() {
// Prüfen, ob die Parameter korrekt sind
   if(startIndex_ < 0 || startIndex_ + totalStrategies_ > 9) {
      return INIT_PARAMETERS_INCORRECT;
   }

// Erstellen und Auffüllen eines Arrays von Strategieinstanzen
   CStrategy *strategies[9];

   StrategyInput InputBase;
   SimpleVolumesStrategyInput Input;

   InputBase.timeframe = PERIOD_H1;

   // Die erste Art der Einstellung erfolgt durch Initialisierung.
   const StrategyInput InputBase0 = {"EURGBP", PERIOD_H1, NormalizeDouble(0.01 / 0.16 * depoPart_, 2)};
   const SimpleVolumesStrategyInput Input0 = {13, 0.3, 1.0, 0, 10500, 465, 1000, 3};
   strategies[0] = new CSimpleVolumesStrategy(InputBase0 + Input0);

   // Die zweite Möglichkeit der Angabe ist über String und Array.
   InputBase.fixedLot = NormalizeDouble(0.01 / 0.09 * depoPart_, 2);
   const double Array1[] = {17, 1.7, 0.5, 0, 16500, 220, 1000, 3};
   strategies[1] = new CSimpleVolumesStrategy(InputBase["symbol = EURGBP"] + "," + Input[Array1]);

   // Die dritte Möglichkeit der Spezifizierung ist die Feldzuweisung.
   InputBase.fixedLot = NormalizeDouble(0.01 / 0.16 * depoPart_, 2);
   InputBase.symbol = "EURGBP";
   const double Array2[] = {51, 0.5, 1.1, 0, 19500, 370, 22000, 3};
   strategies[2] = new CSimpleVolumesStrategy(InputBase + Input[Array2]);
Dateien:
 
fxsaber #:

Es ist gut, dass sie nicht gepostet haben, denn ich habe sie noch einmal überarbeitet - in der prägnantesten und benutzerfreundlichsten Version (das scheint die endgültige zu sein).

Ja, eine sehr vertraute Situation. Alles scheint da zu sein, und dann überarbeitet man es noch einmal und es ist noch besser. Ich denke, dass dies auch nicht die endgültige Version ist, denn Sie orientieren sich an den Szenarien der Verwendung von Parametern im Code, die bereits veröffentlicht wurden. Wenn es darum geht, Parameter in Sets einzubauen, und noch mehr, wenn es darum geht, automatisch in Sets einzubauen, werden Sie wahrscheinlich feststellen, dass Sie das Ganze auch noch verbessern/vereinfachen können.

Danke!!!