Diskussion zum Artikel "Entwicklung eines Expertenberaters für mehrere Währungen (Teil 1): Zusammenarbeit von mehreren Handelsstrategien" - Seite 2

 
fxsaber #:

Es wird nicht schaden, 100%. Es ist nur eine unnötige Einheit. OOP folgt architektonisch dem Prinzip vom Allgemeinen zum Besonderen. Sie haben das Allgemeine (Basisklasse) "privat" gemacht. Obwohl alles, was dort aufgerufen wird, CStrategy::Tick() ist.

Das ist der Ansatz, den ich hier gewählt habe. Angenommen, wir können eine lineare Hierarchie Basisklasse -> Erbenklasse1 -> Erbenklasse2 -> Erbenklasse3 erstellen. Die Erbenklassen verkomplizieren nach und nach ihre Elternklasse, aber der Vererbungsbaum verzweigt sich nirgends, d. h. alle Klassen haben nur einen aufeinander folgenden Erben. Wenn wir also echte Objekte aus nur wenigen Klassen erstellen wollen, die die Nachfolger von Inheritor3 sein werden, und der gesamte Code der Elternklassen kompakt genug ist, erstellen wir eine Basisklasse auf einmal, die den Inhalt der ersten drei Nachfolger enthält.

In diesem Artikel enthält die Basisklasse im Großen und Ganzen wirklich nur CStrategy::Tick(). Es ist jedoch geplant, in Zukunft allgemeineren Code für alle Strategien hinzuzufügen.

 
fxsaber #:

Es scheint ein Compiler-Fehler zu sein, dass er nicht auf diese Methodensignatur schimpft, wenn sie so aufgerufen wird.

Hier liegt es, so wie ich es verstehe, daran, dass Zeiger in MQL5 nicht dasselbe sind wie Zeiger in C++. Deshalb ist diese Variante geeignet.

 
fxsaber CObject.

Sie verwenden es nicht.


Ich habe festgestellt, dass es durchaus üblich ist, von CObject zu erben.

Ich verstehe nicht ganz, was genau nicht verwendet wird, obwohl es das sein könnte?

Die Vererbung von CObject wird nur aus Gründen der späteren Verwendung von Save() und Load() durchgeführt.

 
Yuriy Bykov #:

Ich verstehe nicht ganz, was genau nicht verwendet wird, obwohl es verwendet werden könnte?

Ich werde den Code vollständig wiedergeben.

class CObject
  {
private:
   CObject          *m_prev;               // vorheriger Punkt der Liste
   CObject          *m_next;               // nächster Punkt der Liste

public:
                     CObject(void): m_prev(NULL),m_next(NULL)            {                 }
                    ~CObject(void)                                       {                 }
   //--- Methoden für den Zugriff auf geschützte Daten
   CObject          *Prev(void)                                    const { return(m_prev); }
   void              Prev(CObject *node)                                 { m_prev=node;    }
   CObject          *Next(void)                                    const { return(m_next); }
   void              Next(CObject *node)                                 { m_next=node;    }
   //--- Methoden für die Arbeit mit Dateien
   virtual bool      Save(const int file_handle)                         { return(true);   }
   virtual bool      Load(const int file_handle)                         { return(true);   }
   //--- Methode zur Identifizierung des Objekts
   virtual int       Type(void)                                    const { return(0);      }
   //--- Methode zum Vergleich der Objekte
   virtual int       Compare(const CObject *node,const int mode=0) const { return(0);      }
  };

Kurz gesagt, diese Klasse ist für die Bildung von und die Arbeit mit Listen gedacht, einschließlich einer möglichen Sortierung.

Die Vererbung von CObject erfolgt nur, um später Save() und Load() verwenden zu können

Aus einer Kanone auf Spatzen. Warum nicht diese beiden virtuellen Methoden zu CStrategy hinzufügen?

 
fxsaber #:

Aus einer Kanone auf Spatzen. Warum nicht diese beiden virtuellen Methoden zu CStrategy hinzufügen?

Ja, ich stimme zu. Ich werde die Speichermethoden zu CStrategy und den übrigen Basisklassen hinzufügen, anstatt von CObject zu erben

 
Yuriy Bykov #:

Sie machen OOP-Konvertierung von klassischer (Eingabe + ohne OOP) SimpleVolumes.mq5 in SimpleVolumesStartegy.mqh.

Warum haben Sie SimpleVolumes.mq5 nicht über #include SimpleVolumesStartegy.mqh erstellt?

 
fxsaber #:

können Sie die Schwerfälligkeit bei der Eingabe aufgrund von OOP deutlich erkennen. Es wäre gut, sie zu entfernen.

Getarnt.

int OnInit() {
   expert.AddStrategy(new CSimpleVolumeStrategy(
                         magic_ + 1, "EURGBP", PERIOD_H1,
                         NormalizeDouble(0.34 * depoPart_, 2),
                         130, 0.9, 1.4, 231, 3750, 50, 600, 3)
                     );
   expert.AddStrategy(new CSimpleVolumeStrategy(
                         magic_ + 2, "EURGBP", PERIOD_H1,
                         NormalizeDouble(0.10 * depoPart_, 2),
                         159, 1.7, 0.8, 248, 3600, 495, 39000, 3)
                     );

   int res = expert.Init();   // Initialisierung aller Expert Advisor Strategien

   return(res);
}

Da sie begonnen haben, die Arbeit des TC-Portfolios zu zeigen, wäre es gut, mit dem Laden des Portfolios (Eingaben) richtig umzugehen.

 
fxsaber #:

Sie machen eine OOP-Konvertierung von der klassischen (input + no OOP) SimpleVolumes.mq5 zu SimpleVolumesStartegy.mqh.

Warum haben Sie SimpleVolumes.mq5 nicht über #include SimpleVolumesStartegy.mqh erstellt?

Weil ich den Prozess des Übergangs von einem normalen EA (input + ohne OOP), der ohne das Ziel der parallelen Nutzung mit verschiedenen Einstellungen geschrieben wurde (das ist die SimpleVolumes.mq5 Rolle) zu einem anderen EA, in dem diese parallele Nutzung möglich ist (das ist die SimpleVolumesExpert.mq5 Rolle), demonstrieren wollte. Zu diesem Zweck benötigten wir eine OOP-Transformation in SimpleVolumesStartegy.mqh.

 
fxsaber #:

Da sie begonnen haben, die Arbeit des TZ-Portfolios zu zeigen, wäre es gut, mit der Portfolioladung (Inputs) kompetent umzugehen.

Wir werden uns auf jeden Fall in den nächsten Teilen damit befassen. Es gibt noch eine Menge Dinge zu behandeln, so dass es nicht möglich war, alles auf einmal zu präsentieren.

Ich bin sehr dankbar für alle Kommentare, denn jetzt ist der richtige Zeitpunkt dafür - für Artikel, die ich fast von Grund auf neu schreibe, habe ich in den letzten Jahren einen Code geschrieben, der nicht ohne Not bereinigt und optimiert wurde. Der Code erfüllt also seine Aufgabe, aber es gibt einige Stellen, die nicht mehr benötigt werden, aber nicht bereinigt wurden, sowie einige Stellen, an denen man, wie man jetzt sehen kann, den Code vereinfachen oder generell einen anderen Architekturansatz anwenden kann.

Im Idealfall würde ich gerne die Optimierung und die Auswahl eines guten Portfolios von Strategieparametern mit Hilfe Ihrer hervorragenden Bibliotheken vollständig automatisieren.

 
Yuriy Bykov #:

Weil ich den Prozess der Umstellung von einem normalen EA (Eingabe + ohne OOP) demonstrieren wollte

Ich habe es.