Diskussion zum Artikel "Der MQL5 Assistent: Wie man ein Modul an Handelssignalen erzeugt" - Seite 6

 
Karputov Vladimir:
Oder ein Geldverwaltungsmodul. Für welches man sich entscheidet, muss man sich genauer ansehen.

Das Konzept ist nicht sehr klar. Es gibt Signale für die Eröffnung von Positionen, aber auch für deren Schließung. Es wäre möglich, Abstimmungen usw. zu verwenden, und das alles zusätzlich zum Trailing.

Und wie oft ändern sich die Basisklassen? Wenn ich mein Signalmodul mit der vorherigen Version des Assistenten geschrieben hätte, müsste ich es jetzt neu entwerfen.

Ich frage mich nur, ob irgendjemand ernsthaft diesen Assistenten und die Expert Advisors-Basisklassen verwendet, oder ob das nur für faule Leute ist, die nichts selbst machen wollen?

 
Karputov Vladimir:
Oder ein Geldverwaltungsmodul. Was genau zu wählen ist, müssen Sie sich genauer ansehen.

Es tut mir leid, ich bin nicht gut in OOP, können Sie mir helfen, es zu verstehen?

Hier habe ich ein Modul der Handelssignale mit dem Namen СMySignal.mqh erstellt. Jetzt möchte ich meine eigenen Schließungssignale implementieren. Dafür erstelle ich mein eigenes Kapitalmanagementmodul CMyMoney.mqh, weil CExpert einen solchen Aufruf hat:

protected:
  CExpertMoney     *m_money;

bool CExpert::CheckClose(void)

  {
   double lot;
//--- position must be selected before call
   if((lot=m_money.CheckClose(GetPointer(m_position)))!=0.0)
      return(CloseAll(lot));

Aber ich möchte die Methoden der Klasse CMySignal in der Schließungslogik verwenden, ich möchte nicht alle Berechnungen in CMyMoney erneut durchführen. Also schreibe ich in CMyMoney etwas wie dieses:

class CMyMoney : public CExpertMoney

protected:

   //--- input parameters
   virtual bool      CheckCloseLong(void);
   virtual bool      CheckCloseShort(void);

   CMySignal         *filter0;

...

double CMyMoney::CheckClose(CPositionInfo *position)
  {
   double lot;
   lot=position.Volume();
   if(position.PositionType()==POSITION_TYPE_BUY)
     {
      //--- check the possibility of closing the long position
      if(filter0.CheckCloseLong(lot))
         Print(__FUNCTION__+": close long position signal detected. Lot to be closed ",lot); 
     }
   else
     {
      //--- check the possibility of closing the short position
      if(filter0.CheckCloseShort(lot))
         Print(__FUNCTION__+": close short position signal detected. Lot to be closed ",lot);
     }
   return(lot);
  }


Und verschiebe die gesamte Abschlusslogik in die CMySignal-Klasse:

class CMySignal : public CExpertSignal

public:

   virtual bool      CheckCloseLong(double &lot);
   virtual bool      CheckCloseShort(double &lot);

bool CMySignal::CheckCloseLong(double &lot)

  {

   //логика закрытия Long

  }

bool CMySignal::CheckCloseShort(double &lot)

  {

   //логика закрытия Short

  }

Aber es stellt sich heraus, dass ich es bereits mit einem neuen filter0-Objekt zu tun habe, nicht mit einem bereits erstellten. Ich muss die Daten dafür neu initialisieren (Indikatoren und so weiter). Wie erhalte ich Zugriff auf das bereits vorhandene Objekt der Klasse CMySignal? Ich hoffe, ich habe mich klar ausgedrückt =)

Das Ganze soll standardmäßig über den Wizard funktionieren, ich ändere also keine Basisklassen. Alle Änderungen sind nur in meinen Handelssignalen und Geldverwaltungsmodulen möglich.

 
t101:

Es tut mir leid, ich bin nicht gut in OOP, können Sie mir helfen, es zu verstehen?

Ich habe ein Modul der Handelssignale mit dem Namen СMySignal.mqh erstellt. Jetzt möchte ich meine eigenen Schließungssignale implementieren. Dafür erstelle ich mein eigenes Kapitalmanagementmodul CMyMoney.mqh, weil CExpert einen solchen Aufruf hat:

protected:
  CExpertMoney     *m_money;

bool CExpert::CheckClose(void)

  {
   double lot;
//--- position must be selected before call
   if((lot=m_money.CheckClose(GetPointer(m_position)))!=0.0)
      return(CloseAll(lot));

Aber ich möchte die Methoden der Klasse CMySignal in der Schließungslogik verwenden, ich möchte nicht alle Berechnungen in CMyMoney erneut durchführen. Also schreibe ich in CMyMoney etwas wie dieses:

class CMyMoney : public CExpertMoney

protected:

   //--- input parameters
   virtual bool      CheckCloseLong(void);
   virtual bool      CheckCloseShort(void);

   CMySignal         *filter0;

...

double CMyMoney::CheckClose(CPositionInfo *position)
  {
   double lot;
   lot=position.Volume();
   if(position.PositionType()==POSITION_TYPE_BUY)
     {
      //--- check the possibility of closing the long position
      if(filter0.CheckCloseLong(lot))
         Print(__FUNCTION__+": close long position signal detected. Lot to be closed ",lot); 
     }
   else
     {
      //--- check the possibility of closing the short position
      if(filter0.CheckCloseShort(lot))
         Print(__FUNCTION__+": close short position signal detected. Lot to be closed ",lot);
     }
   return(lot);
  }


Und verschiebe die gesamte Abschlusslogik in die CMySignal-Klasse:

class CMySignal : public CExpertSignal

public:

   virtual bool      CheckCloseLong(double &lot);
   virtual bool      CheckCloseShort(double &lot);

bool CMySignal::CheckCloseLong(double &lot)

  {

   //логика закрытия Long

  }

bool CMySignal::CheckCloseShort(double &lot)

  {

   //логика закрытия Short

  }

Aber es stellt sich heraus, dass ich es bereits mit einem neuen filter0-Objekt zu tun habe, nicht mit einem bereits erstellten. Ich muss die Daten dafür neu initialisieren (Indikatoren und so weiter). Wie erhalte ich Zugriff auf das bereits vorhandene Objekt der Klasse CMySignal? Ich hoffe, ich habe mich klar ausgedrückt =)

Das Ganze soll standardmäßig über den Wizard funktionieren, ich ändere also keine Basisklassen. Alle Änderungen sind nur in meinen Handelssignalen und Geldverwaltungsmodulen möglich.

Ich habe eine Frage zum zweiten "Blatt" - warum fügen Sie"CMySignal *filter0;" in das Geldverwaltungsmodul ein?
 
Karputov Vladimir:
Ich habe eine Frage zum zweiten "Blatt" - warum fügen Sie"CMySignal *filter0;" in das Geldverwaltungsmodul ein?

filter0 ist ein Klassenobjekt meines Handelssignalmoduls CMySignal. Es wird in der Hauptdatei des Expert Advisors erstellt:

CMySignal *filter0=new CMySignal;

Ich versuche, vom Geldverwaltungsmodul darauf zuzugreifen, um alle Abschlussberechnungen an mein Signalmodul zu übertragen. Ich sehe keine anderen Möglichkeiten, meine eigene Abschlusslogik zu implementieren.
 
t101:

filter0 ist ein Klassenobjekt meines Handelssignalmoduls CMySignal. Es wird in der EA-Hauptdatei erstellt:

CMySignal *filter0=new CMySignal;

Ich versuche, vom Geldverwaltungsmodul darauf zuzugreifen, um alle Abschlussberechnungen an mein Signalmodul zu übertragen. Ich sehe keine anderen Möglichkeiten, meine eigene Abschlusslogik zu implementieren.

Sehen Sie sich die Implementierung der Übertragung des Zeigers auf das Hauptsignal an das Signalmodul an(MQL5 Wizard: How to teach an Expert Advisor to open pending orders at any price):

Nach unserem Schema der Ideenimplementierung ist es notwendig, eine interne Variable zu deklarieren, in der der Zeiger auf das Hauptsignal gespeichert werden soll.

Da diese Variable intern sein muss (mit Geltungsbereich nur innerhalb der Klasse des Handelssignalgenerators), fügen wir sie dem nächsten Codeblock hinzu:

protected:
   CiEnvelopes       m_env;          // Objekt-Indikator
   //--- angepasste Parameter
   int               m_ma_period;    // der Parameter "Mittelungszeitraum" des Indikators
   int               m_ma_shift;     // der Parameter "Zeitverschiebung" des Indikators
   ENUM_MA_METHOD    m_ma_method;     // den Parameter "Methode der Mittelwertbildung" des Indikators
   ENUM_APPLIED_PRICE m_ma_applied;    // der Parameter "Objekt der Mittelwertbildung" des Indikators
   double            m_deviation;    // der Parameter "Abweichung" des Indikators
   //--- "Gewichte" der Marktmodelle (0-100)
   int               m_pattern_0;      // Modell 0
   CExpertSignal    *m_signal;         // Verweis auf das Hauptsignal speichern

Beachten Sie auch, dass ich die Variablen, die im Code nicht verwendet werden, entfernt habe.

Wir werden die Methode, mit der der Zeiger auf das Hauptsignal gespeichert wird, in einem anderen Codeblock deklarieren - "Methode zum Setzen des Zeigers auf das Hauptsignal". Einige unnötige Methoden wurden ebenfalls entfernt.

Vielleicht ist das genau das, was Sie brauchen. Nur der Zeiger auf das Hauptsignal wird an das Kapitalverwaltungsmodul weitergegeben.

 
Karputov Vladimir:

Sehen Sie sich die Implementierung der Übergabe des Zeigers auf das Hauptsignal an das Signalmodul an(MQL5 Wizard: How to teach the Expert Advisor to open pending orders at any price):

Vielleicht ist es das, was Sie brauchen. Nur der Zeiger auf das Hauptsignal wird an das Geldverwaltungsmodul weitergegeben.

Wozu brauche ich einen Zeiger auf das Hauptsignal, wenn ich einen Zeiger auf mein Signal, einen Erben der Klasse CExpertSignal, brauche? Ich möchte es in meinem Geldverwaltungsmodul, einem Nachkommen von CExpertMoney.
 
t101:
Warum brauche ich einen Zeiger auf das Kopfsignal, wenn ich einen Zeiger auf mein Signal, einen Abkömmling der Klasse CExpertSignal, haben möchte? Ich will es in meinem Geldverwaltungsmodul, einem Erben von CExpertMoney.

Nun gut. Gehen wir auf die andere Seite. In Ihrem Geldverwaltungsmodul müssen Sie eine Variable wie diese deklarieren:

CMySignal    *m_signal;         // einen Verweis auf Ihr Signal speichern

und eine Methode wie diese:

   //--- Methode zum Setzen des Zeigers auf das Hauptsignal
   virtual bool      InitSignal(СMySignal *filter=NULL);

und ihre Implementierung

//+------------------------------------------------------------------+
//| Initialisierungssignalobjekt|
//+------------------------------------------------------------------+
bool CMyMoney::InitSignal(СMySignal *filter)
  {
   m_signal=filter;
   return(true);
  }

Nun können Sie versuchen, Ihr Signal aus dem Geldverwaltungsmodul über

m_signal.метод вашего модуля сигналов
 
Karputov Vladimir:

Nun gut. Gehen wir auf die andere Seite. In Ihrem Geldverwaltungsmodul müssen Sie eine Variable wie diese deklarieren:

und diese Methode:

und ihre Implementierung

Jetzt kann ich versuchen, auf mein Signal aus dem Geldverwaltungsmodul zuzugreifen über

Ungültiger Zeigerzugriff beim Aufruf einer Methode meines Signalmoduls
m_signal.метод вашего модуля сигналов
InitSignal muss vorher irgendwo aufgerufen werden?
 
t101:
Ungültiger Zeigerzugriff beim Aufruf einer Methode meines Signalmoduls
InitSignal muss vorher irgendwo aufgerufen werden?
Natürlich sollte "InitSignal" vorher aufgerufen werden: aus OnInit() des EA, am Ende des Initialisierungsblocks des Money Management Moduls.
 
Karputov Vladimir:
Natürlich müssen wir "InitSignal" früher aufrufen: von OnInit() des EA, am Ende des Initialisierungsblocks des Geldverwaltungsmoduls.
Soll ich es manuell zu OnInit() hinzufügen? Ich kann also nicht über den Assistenten tun, was ich will?