Discussion de l'article "Assistant MQL5 : Comment Créer un Module de Signaux de Trading" - page 6

 
Karputov Vladimir:
Ou un module de gestion de l'argent. Pour savoir lequel choisir, il convient d'examiner la question plus en détail.

Le concept n'est pas très clair. Il existe des signaux d'ouverture de positions, mais aussi des signaux de fermeture de positions. Il serait possible d'utiliser le vote et ainsi de suite, et tout cela en plus du suivi.

Et à quelle fréquence les classes de base changent-elles ? Si j'ai écrit mon module de signaux avec la version précédente de l'assistant, je devrais le redessiner maintenant.

Je me demande simplement si quelqu'un utilise sérieusement cet assistant et les classes de base Expert Advisors ou si c'est seulement pour les paresseux qui ne veulent rien faire à la main ?

 
Karputov Vladimir:
Ou un module de gestion de l'argent. Pour savoir exactement ce qu'il faut choisir, il faut examiner la question plus en détail.

Je suis désolé, je ne suis pas bon en OOP, pouvez-vous m'aider à comprendre ?

Ici, j'ai créé un module de signaux de trading appelé СMySignal.mqh. Maintenant, je veux implémenter mes propres signaux de clôture. Pour cela, je crée mon propre module de gestion de capital CMyMoney.mqh car CExpert dispose d'un tel appel :

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));

Mais je veux utiliser les méthodes de la classe CMySignal dans la logique de clôture, je ne veux pas refaire tous les calculs dans CMyMoney. Donc, dans CMyMoney, j'écris quelque chose comme ceci :

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);
  }


Et je déplace toute la logique de fermeture dans la classe CMySignal :

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

  }

Mais il s'avère que j'ai déjà affaire à un nouvel objet filter0, et non à un objet déjà créé. Je dois réinitialiser les données (indicateurs, etc.). Comment puis-je accéder à l'objet déjà existant de la classe CMySignal ? J'espère avoir été clair =)

Tout ceci devrait fonctionner à travers l'assistant de manière standard, donc je ne change aucune classe de base. Toutes les modifications ne sont possibles que dans mes modules de signaux de trading et de gestion de l'argent.

 
t101:

Je suis désolé, je ne suis pas bon en OOP, pouvez-vous m'aider à comprendre ?

J'ai créé un module de signaux de trading appelé СMySignal.mqh. Je souhaite maintenant implémenter mes propres signaux de clôture. Pour cela, je crée mon propre module de gestion de capital CMyMoney.mqh car CExpert dispose d'un tel appel :

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));

Mais je veux utiliser les méthodes de la classe CMySignal dans la logique de clôture, je ne veux pas refaire tous les calculs dans CMyMoney. Donc, dans CMyMoney, j'écris quelque chose comme ceci :

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);
  }


Et je déplace toute la logique de fermeture dans la classe CMySignal :

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

  }

Mais il s'avère que j'ai déjà affaire à un nouvel objet filter0, et non à un objet déjà créé. Je dois réinitialiser les données (indicateurs, etc.). Comment puis-je accéder à l'objet déjà existant de la classe CMySignal ? J'espère avoir été clair =)

Tout ceci devrait fonctionner à travers l'assistant de manière standard, donc je ne change aucune classe de base. Tous les changements ne sont possibles que dans mes modules de signaux de trading et de gestion de l'argent.

J'ai une question sur la deuxième "feuille" - pourquoi insérez-vous"CMySignal *filter0 ;" dans le module de gestion de l'argent ?
 
Karputov Vladimir:
J'ai une question concernant la deuxième "feuille" - pourquoi insérez-vous"CMySignal *filter0 ;" dans le module de gestion de l'argent ?

filter0 est un objet de classe de mon module de signaux de trading CMySignal. Il est créé dans le fichier principal du conseiller expert :

CMySignal *filter0=new CMySignal;

J'essaie d'y accéder à partir du module de gestion de l'argent pour transférer tous les calculs de clôture à mon module de signaux. Je ne vois pas d'autres moyens d'implémenter ma propre logique de clôture.
 
t101:

filter0 est un objet de classe de mon module de signaux de trading CMySignal. Il est créé dans le fichier EA principal :

CMySignal *filter0=new CMySignal;

J'essaie d'y accéder à partir du module de gestion de l'argent pour transférer tous les calculs de clôture à mon module de signaux. Je ne vois pas d'autres moyens d'implémenter ma propre logique de clôture.

Regardez la mise en œuvre du transfert du pointeur vers le signal principal vers le module de signaux(Assistant MQL5 : Comment apprendre à un Expert Advisor à ouvrir des ordres en attente à n'importe quel prix) :

Selon notre schéma de mise en œuvre de l'idée, il est nécessaire de déclarer une variable interne dans laquelle le pointeur sur le signal principal sera stocké.

Comme cette variable doit être interne (avec une portée uniquement à l'intérieur de la classe du générateur de signaux de trading), nous l'ajouterons au bloc de code suivant :

protected:
   CiEnvelopes       m_env;          // indicateur d'objet
   //--- paramètres ajustés
   int               m_ma_period;    // le paramètre "période de calcul de la moyenne" de l'indicateur
   int               m_ma_shift;     // le paramètre "décalage horaire" de l'indicateur
   ENUM_MA_METHOD    m_ma_method;     // le paramètre "méthode de calcul de la moyenne" de l'indicateur
   ENUM_APPLIED_PRICE m_ma_applied;    // le paramètre "objet de la moyenne" de l'indicateur
   double            m_deviation;    // le paramètre "écart" de l'indicateur
   //--- "poids" des modèles de marché (0-100)
   int               m_pattern_0;      // modèle 0
   CExpertSignal    *m_signal;         // stocker la référence au signal principal

Notez également que j'ai supprimé les variables qui ne seront pas utilisées dans le code.

Nous déclarerons la méthode qui sera utilisée pour stocker le pointeur sur le signal principal dans un autre bloc de code - "method of setting the pointer to the main signal". Certaines méthodes inutiles ont également été supprimées.

C'est peut-être ce dont vous avez besoin. Seul le pointeur sur le signal principal sera transmis au module de gestion du capital.

 
Karputov Vladimir:

Regardez la mise en œuvre du passage du pointeur vers le signal principal au module de signal(Assistant MQL5 : Comment apprendre à l'Expert Advisor à ouvrir des ordres en attente à n'importe quel prix) :

C'est peut-être ce dont vous avez besoin. Seul le pointeur sur le signal principal sera transmis au module de gestion financière.

Pourquoi ai-je besoin d'un pointeur sur le signal principal si j'ai besoin d'un pointeur sur mon signal, qui hérite de la classe CExpertSignal ? Je le veux dans mon module de gestion de l'argent, un descendant de CExpertMoney.
 
t101:
Pourquoi ai-je besoin d'un pointeur sur le signal de tête si je veux un pointeur sur mon signal, un descendant de la classe CExpertSignal ? Je le veux dans mon module de gestion de l'argent, un héritier de CExpertMoney.

Je le veux dans mon module de gestion de l'argent, un héritier de CExpertMoney. Passons à l'autre côté. Dans votre module de gestion de l'argent, vous devez déclarer une variable comme celle-ci :

CMySignal    *m_signal;         // stocker une référence à votre signal

et une méthode comme ceci :

   //--- méthode de mise en place du pointeur sur le signal principal
   virtual bool      InitSignal(СMySignal *filter=NULL);

et son implémentation

//+------------------------------------------------------------------+
//| Objet du signal d'initialisation|
//+------------------------------------------------------------------+
bool CMyMoney::InitSignal(СMySignal *filter)
  {
   m_signal=filter;
   return(true);
  }

Vous pouvez maintenant essayer d'accéder à votre signal depuis le module de money management via

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

C'est très bien. Passons à l'autre côté. Dans votre module de gestion de l'argent, vous devez déclarer une variable comme celle-ci :

et cette méthode :

et son implémentation

Maintenant je peux essayer d'accéder à mon signal depuis le module de money management via

Accès au pointeur invalide lors de l'appel d'une méthode de mon module de signal
m_signal.метод вашего модуля сигналов
InitSignal doit être appelé quelque part avant ?
 
t101:
Invalid pointer access when calling a method of my signals module
InitSignal doit être appelé quelque part avant ?
Bien sûr, "InitSignal" doit être appelé avant : à partir de OnInit() de l'EA, à la fin du bloc d'initialisation du module de money management.
 
Karputov Vladimir:
Bien sûr, nous devons appeler "InitSignal" plus tôt : à partir de OnInit() de l'EA, à la fin du bloc d'initialisation du module de money management.
Dois-je l'ajouter manuellement à OnInit() ? Je ne peux donc pas faire ce que je veux avec l'assistant ?