Discussione sull’articolo "Il Wizard MQL5: Come creare un modulo di segnali di trading" - pagina 6

 
Karputov Vladimir:
Oppure un modulo di gestione del denaro. Quale scegliere, è necessario esaminarlo in modo più approfondito.

Il concetto non è molto chiaro. Esistono segnali per l'apertura di posizioni, ma anche per la loro chiusura. Sarebbe possibile utilizzare il voto e così via, e tutto questo in aggiunta al trailing.

E quanto spesso cambiano le classi base? Se ho scritto il mio modulo di segnali con la versione precedente della procedura guidata, dovrei riprogettarlo ora.

Mi chiedo solo se qualcuno utilizza seriamente questa procedura guidata e le classi base degli Expert Advisor o se è solo per i pigri che non vogliono fare nulla da soli.

 
Karputov Vladimir:
Oppure un modulo di gestione del denaro. Cosa scegliere esattamente, è necessario esaminare la questione in modo più dettagliato.

Mi dispiace, non sono bravo in OOP, potete aiutarmi a capirlo?

Ho creato un modulo di segnali di trading chiamato СMySignal.mqh. Ora voglio implementare i miei segnali di chiusura. Per questo creo il mio modulo di gestione del capitale CMyMoney.mqh perché CExpert ha una chiamata di questo tipo:

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

Ma voglio utilizzare i metodi della classe CMySignal nella logica di chiusura, non voglio rifare tutti i calcoli in CMyMoney. Quindi in CMyMoney scrivo qualcosa di simile:

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


E sposto tutta la logica di chiusura nella 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

  }

Ma si scopre che ho già a che fare con un nuovo oggetto filter0 e non con uno già creato. Devo quindi reinizializzare i dati (indicatori e così via). Come posso accedere all'oggetto già esistente della classe CMySignal? Spero di essere stato chiaro =)

Tutto questo dovrebbe funzionare attraverso la procedura guidata in modo standard, quindi non devo cambiare nessuna classe base. Tutte le modifiche sono possibili solo nei miei segnali di trading e nei moduli di gestione del denaro.

 
t101:

Mi dispiace, non sono bravo in OOP, potete aiutarmi a capirlo?

Ho creato un modulo di segnali di trading chiamato СMySignal.mqh. Ora voglio implementare i miei segnali di chiusura. Per questo creo il mio modulo di gestione del capitale CMyMoney.mqh perché CExpert ha una chiamata di questo tipo:

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

Ma voglio utilizzare i metodi della classe CMySignal nella logica di chiusura, non voglio rifare tutti i calcoli in CMyMoney. Quindi in CMyMoney scrivo qualcosa di simile:

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


E sposto tutta la logica di chiusura nella 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

  }

Ma si scopre che ho già a che fare con un nuovo oggetto filter0 e non con uno già creato. Devo quindi reinizializzare i dati (indicatori e così via). Come posso accedere all'oggetto già esistente della classe CMySignal? Spero di essere stato chiaro =)

Tutto questo dovrebbe funzionare attraverso la procedura guidata in modo standard, quindi non devo cambiare nessuna classe base. Tutte le modifiche sono possibili solo nei miei segnali di trading e nei moduli di gestione del denaro.

Ho una domanda sul secondo "foglio": perché inserisci"CMySignal *filter0;" nel modulo di gestione del denaro?
 
Karputov Vladimir:
Ho una domanda sul secondo "foglio": perché si inserisce"CMySignal *filter0;" nel modulo di gestione del denaro?

filter0 è un oggetto di classe del mio modulo di segnali di trading CMySignal. Viene creato nel file principale dell'Expert Advisor:

CMySignal *filter0=new CMySignal;

Sto cercando di accedervi dal modulo di gestione del denaro per trasferire tutti i calcoli di chiusura al mio modulo di segnali. Non vedo altri modi per implementare la mia logica di chiusura.
 
t101:

filter0 è una classe oggetto del mio modulo di segnali di trading CMySignal. Viene creato nel file principale dell'EA:

CMySignal *filter0=new CMySignal;

Sto cercando di accedervi dal modulo di gestione del denaro per trasferire tutti i calcoli di chiusura al mio modulo di segnali. Non vedo altri modi per implementare la mia logica di chiusura.

Guardate l'implementazione del trasferimento del puntatore al segnale principale al modulo segnali(MQL5 Wizard: Come insegnare a un Expert Advisor ad aprire ordini pendenti a qualsiasi prezzo):

Secondo il nostro schema di implementazione dell'idea, è necessario dichiarare una variabile interna in cui verrà memorizzato il puntatore al segnale principale.

Poiché questa variabile deve essere interna (con ambito solo all'interno della classe del generatore di segnali di trading), la aggiungeremo al prossimo blocco di codice:

protected:
   CiEnvelopes       m_env;          // Indicatore di oggetto
   //--- parametri adattati
   int               m_ma_period;    // il parametro "periodo di mediazione" dell'indicatore
   int               m_ma_shift;     // il parametro "spostamento temporale" dell'indicatore
   ENUM_MA_METHOD    m_ma_method;     // il parametro "metodo di mediazione" dell'indicatore
   ENUM_APPLIED_PRICE m_ma_applied;    // il parametro "oggetto di mediazione" dell'indicatore
   double            m_deviation;    // il parametro "deviazione" dell'indicatore
   //--- "pesi" dei modelli di mercato (0-100)
   int               m_pattern_0;      // modello 0
   CExpertSignal    *m_signal;         // memorizzare il riferimento al segnale principale

Notate anche che ho rimosso le variabili che non verranno utilizzate nel codice.

Dichiareremo il metodo che verrà utilizzato per memorizzare il puntatore al segnale principale in un altro blocco di codice - "metodo di impostazione del puntatore al segnale principale". Sono stati rimossi anche alcuni metodi non necessari.

Forse questo è ciò di cui avete bisogno. Solo il puntatore al segnale principale verrà passato al modulo di gestione del capitale.

 
Karputov Vladimir:

Guardate l'implementazione del passaggio del puntatore al segnale principale al modulo del segnale(MQL5 Wizard: Come insegnare all'Expert Advisor ad aprire ordini pendenti a qualsiasi prezzo):

Forse questo è ciò di cui avete bisogno. Solo il puntatore al segnale principale verrà passato al modulo di gestione del denaro.

Perché ho bisogno di un puntatore al segnale principale se ho bisogno di un puntatore al mio segnale, ereditario della classe CExpertSignal? Lo voglio nel mio modulo di gestione del denaro, un discendente di CExpertMoney.
 
t101:
Perché ho bisogno di un puntatore al segnale head se voglio un puntatore al mio segnale, un discendente della classe CExpertSignal? Lo voglio nel mio modulo di gestione del denaro, che è un erede di CExpertMoney.

Ok. Passiamo all'altro lato. Nel vostro modulo di gestione del denaro, dovete dichiarare una variabile come questa:

CMySignal    *m_signal;         // memorizzare un riferimento al segnale

e un metodo come questo:

   //--- metodo per impostare il puntatore al segnale principale
   virtual bool      InitSignal(СMySignal *filter=NULL);

e la sua implementazione

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

Ora si può provare ad accedere al proprio segnale dal modulo di gestione del denaro tramite

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

Va bene. Passiamo all'altro lato. Nel modulo di gestione del denaro, è necessario dichiarare una variabile come questa:

e questo metodo:

e la sua implementazione

Ora posso provare ad accedere al mio segnale dal modulo di gestione del denaro via

Accesso non valido al puntatore quando si chiama un metodo del mio modulo di segnale
m_signal.метод вашего модуля сигналов
InitSignal deve essere chiamato da qualche parte prima?
 
t101:
Accesso non valido al puntatore quando si chiama un metodo del mio modulo segnali
InitSignal deve essere chiamato da qualche parte prima?
Naturalmente "InitSignal" deve essere chiamato prima: da OnInit() dell'EA, alla fine del blocco di inizializzazione del modulo di gestione del denaro.
 
Karputov Vladimir:
Ovviamente dobbiamo chiamare "InitSignal" prima: da OnInit() dell'EA, alla fine del blocco di inizializzazione del modulo di gestione del denaro.
Devo aggiungerlo manualmente a OnInit()? Quindi non posso fare quello che voglio attraverso la procedura guidata?