Discusión sobre el artículo "MQL5 Wizard: Cómo crear un módulo de señales de trading" - página 6

 
Karputov Vladimir:
O un módulo de gestión monetaria. Cuál elegir, hay que mirarlo con más detalle.

El concepto no está muy claro. Hay señales para abrir posiciones, pero también las hay para cerrarlas. Sería posible utilizar la votación y así sucesivamente, y todo esto además de trailing.

¿Y con qué frecuencia cambian las clases base? Si escribí mi módulo de señales con la versión anterior del asistente, ahora tendría que rediseñarlo.

Sólo me preguntaba, ¿alguien utiliza en serio este asistente y las clases base de Expert Advisors o es sólo para perezosos que no quieren hacer nada por sí mismos?

 
Karputov Vladimir:
O un módulo de gestión monetaria. Qué elegir exactamente, tienes que mirarlo con más detalle.

Lo siento, no soy bueno en OOP, ¿puedes ayudarme a entenderlo?

Aquí he hecho un módulo de señales de comercio llamado СMySignal.mqh. Ahora quiero implementar mis propias señales de cierre. Para esto creo mi propio módulo de gestión de capital CMyMoney.mqh porque CExpert tiene tal llamada:

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

Pero quiero utilizar los métodos de la clase CMySignal en la lógica de cierre, no quiero volver a hacer todos los cálculos en CMyMoney. Así que en CMyMoney escribo algo como esto:

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


Y muevo toda la lógica de cierre a la clase 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

  }

Pero resulta que ya estoy tratando con un nuevo objeto filter0, no con uno ya creado. Tengo que reinicializar los datos del mismo (indicadores y demás). ¿Cómo puedo acceder al objeto ya existente de la clase CMySignal? Espero haberme explicado bien =)

Todo esto debería funcionar a través del Asistente de una manera estándar, por lo que no cambio ninguna clase base. Todos los cambios sólo son posibles en mis señales de comercio y módulos de gestión de dinero.

 
t101:

Lo siento, no soy bueno en OOP, ¿puedes ayudarme a entenderlo?

He hecho un módulo de señales de comercio llamado СMySignal.mqh. Ahora quiero implementar mis propias señales de cierre. Para esto creo mi propio módulo de gestión de capital CMyMoney.mqh porque CExpert tiene tal llamada:

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

Pero quiero utilizar los métodos de la clase CMySignal en la lógica de cierre, no quiero volver a hacer todos los cálculos en CMyMoney. Así que en CMyMoney escribo algo como esto:

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


Y muevo toda la lógica de cierre a la clase 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

  }

Pero resulta que ya estoy tratando con un nuevo objeto filter0, no con uno ya creado. Tengo que reinicializar los datos del mismo (indicadores y demás). ¿Cómo puedo acceder al objeto ya existente de la clase CMySignal? Espero haberme explicado bien =)

Todo esto debería funcionar a través del Asistente de una manera estándar, por lo que no cambio ninguna clase base. Todos los cambios sólo son posibles en mis señales de comercio y módulos de gestión de dinero.

Tengo una pregunta sobre la segunda "hoja" - ¿por qué insertar"CMySignal *filter0;" en el módulo de gestión de dinero?
 
Karputov Vladimir:
Tengo una pregunta sobre la segunda "hoja" - ¿por qué insertar"CMySignal *filter0;" en el módulo de gestión de dinero?

filter0 es un objeto de clase de mi módulo de señales de comercio CMySignal. Se crea en el archivo principal del Asesor Experto:

CMySignal *filter0=new CMySignal;

Estoy tratando de obtener acceso a ella desde el módulo de gestión de dinero para transferir todos los cálculos de cierre a mi módulo de señales. No veo ninguna otra manera de implementar mi propia lógica de cierre.
 
t101:

filter0 es una clase objeto de mi módulo de señales de trading CMySignal. Se crea en el archivo principal de EA:

CMySignal *filter0=new CMySignal;

Estoy tratando de acceder a él desde el módulo de administración del dinero para transferir todos los cálculos de cierre a mi módulo de señales. No veo ninguna otra manera de implementar mi propia lógica de cierre.

Mire la implementación de transferir el puntero a la señal principal al módulo de señales(MQL5 Wizard: How to teach an Expert Advisor to open pending orders at any price):

Según nuestro esquema de implementación de la idea, es necesario declarar una variable interna donde se almacenará el puntero a la señal principal.

Dado que esta variable debe ser interna (con ámbito sólo dentro de la clase del generador de señales de trading), la añadiremos al siguiente bloque de código:

protected:
   CiEnvelopes       m_env;          // objeto-indicador
   //--- parámetros ajustados
   int               m_ma_period;    // el parámetro "periodo de promediación" del indicador
   int               m_ma_shift;     // el parámetro "desplazamiento temporal" del indicador
   ENUM_MA_METHOD    m_ma_method;     // el parámetro "método de promediación" del indicador
   ENUM_APPLIED_PRICE m_ma_applied;    // el parámetro "objeto de promedio" del indicador
   double            m_deviation;    // el parámetro "desviación" del indicador
   //--- "pesos" de los modelos de mercado (0-100)
   int               m_pattern_0;      // modelo 0
   CExpertSignal    *m_signal;         // almacenar referencia a la señal principal

Observa también que he eliminado las variables que no se utilizarán en el código.

Declararemos el método, mediante el cual guardaremos el puntero a la señal principal, en otro bloque de código - "método de fijación del puntero a la señal principal". También se han eliminado algunos métodos innecesarios.

Tal vez esto es lo que usted necesita. Sólo el puntero a la señal principal se pasará al módulo de gestión de capital.

 
Karputov Vladimir:

Mire la implementación de pasar el puntero a la señal principal al módulo de señal(MQL5 Wizard: How to teach the Expert Advisor to open pending orders at any price):

Tal vez esto es lo que necesita. Sólo el puntero a la señal principal se pasará al módulo de gestión monetaria.

¿Por qué necesito un puntero a la señal principal si necesito un puntero a mi señal, heredera de la clase CExpertSignal? Lo quiero en mi módulo de gestión monetaria, un descendiente de CExpertMoney.
 
t101:
¿Por qué necesito un puntero a la señal de la cabeza si quiero un puntero a mi señal, un descendiente de la clase CExpertSignal? Lo quiero en mi módulo de gestión de dinero, un heredero de CExpertMoney.

De acuerdo. Vamos al otro lado. En su módulo de gestión de dinero, usted necesita declarar una variable como esta:

CMySignal    *m_signal;         // almacena una referencia a tu señal

y un método como este:

   //--- método de fijación del puntero a la señal principal
   virtual bool      InitSignal(СMySignal *filter=NULL);

y su implementación

//+------------------------------------------------------------------+
//| Objeto señal de inicialización|
//+------------------------------------------------------------------+
bool CMyMoney::InitSignal(СMySignal *filter)
  {
   m_signal=filter;
   return(true);
  }

Ahora puede intentar acceder a su señal desde el módulo de gestión monetaria a través de

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

De acuerdo. Vamos al otro lado. En tu modulo de manejo de dinero, necesitas declarar una variable como esta:

y este método:

y su implementación

Ahora puedo intentar acceder a mi señal desde el módulo de gestión monetaria a través de

Acceso de puntero no válido al llamar a un método de mi módulo de señal
m_signal.метод вашего модуля сигналов
InitSignal debe ser llamado en algún lugar de antemano?
 
t101:
Acceso de puntero inválido al llamar a un método de mi módulo de señales
InitSignal debe ser llamado antes en algún lugar?
Por supuesto que "InitSignal" debe ser llamado antes: desde OnInit() del EA, al final del bloque de inicialización del módulo de gestión monetaria.
 
Karputov Vladimir:
Por supuesto, necesitamos llamar a "InitSignal" antes: desde OnInit() del EA, al final del bloque de inicialización del módulo de gestión monetaria.
¿Debo añadirlo manualmente a OnInit()? ¿Entonces no puedo hacer lo que quiero a través del Asistente?