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

 
t101:
¿Lo añado manualmente en OnInit()? ¿Entonces no puedo hacer lo que quiero a través del Asistente?
¿Cuáles son los problemas? Usted está introduciendo funcionalidad adicional, por lo que necesita hacer un poco de trabajo manual.
 
Karputov Vladimir:
¿Cuál es el problema? Estás introduciendo una funcionalidad adicional, por lo que necesitas hacer un poco de trabajo manual.

No hay problema en absoluto, pero no se corresponde con el concepto de que el Maestro hace todo sobre la base de módulos personalizados para señales, capital, etc. Y el artículo está desactualizado y no es cierto:

El método CheckCloseLong() genera una señal para cerrar una posición larga con la determinación del nivel de salida. Es llamado por el Asesor Experto para determinar la necesidad de cerrar una posición larga. Es necesario anular el método en caso de que se desee generar una señal para cerrar una posición larga.

virtual bool CheckCloseLong(double& price);
En cualquier caso, gracias por su ayuda.
[Eliminado]  
Han pasado casi 6 años, ¿el artículo no está desactualizado? No estoy seguro, ya que veo el terminal actualizado casi todas las semanas.
 
yerlan Imangeldinov:
¿Han pasado casi 6 años y el artículo no está obsoleto? No estoy seguro, ya que veo que el terminal se actualiza casi todas las semanas.
Hay un artículo más reciente sobre cómo escribir módulos de señales de trading:"¡Crea un robot de trading en seis horas!".
 

Hola a todos,

Me pregunto cómo crear un descendiente de CExpertSignal con los dos patrones "break out" y "break in" de un rango de negociación observado utilizando el enfoque propuesto aquí, así como en Exploring Trading Strategy Classes of the Standard Library - Customizing Strategie de Harvester. Mi percepción es que cada clase de señal podría (debería) ser implementada sobrecargando

//+------------------------------------------------------------------+
//| "Votando" que el precio crecerá.|
//| INPUT: no.|
//| OUTPUT: número de "votos" que crecerá el precio. ||
//| OBSERVACIÓN: no.|
//+------------------------------------------------------------------+
int CSignalBreakOutOrIn::LongCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   //--- sólo en caso de que queramos algún tipo de patrón por defecto
   if(IS_PATTERN_USAGE(0)) result=m_pattern_0;                                   // "confirmando" señal número 0
   //--- si se utiliza el modelo 1, compruebe la condición para el patrón 1
   if(IS_PATTERN_USAGE(1) && ConditionForPattern1(idx)) result=m_pattern_1;      // señal número 1
   //--- si se utiliza el modelo 2, compruebe la condición para el patrón 2
   if(IS_PATTERN_USAGE(2) && ConditionForPattern2(idx)) result=m_pattern_2;      // señal número 2
//--- devuelve el resultado
   return(result);
  }

y

//+------------------------------------------------------------------+
//| "Votar" que el precio caerá.|
//| INPUT: no.|
//| OUTPUT: número de "votos" que el precio caerá. ||
//| OBSERVACIÓN: no.|
//+------------------------------------------------------------------+
int CSignalBreakOutOrIn::ShortCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   //--- sólo en caso de que queramos algún tipo de patrón por defecto
   if(IS_PATTERN_USAGE(0)) result=m_pattern_0;                                   // "confirmando" señal número 0
   //--- si se utiliza el modelo 1, compruebe la condición para el patrón 1
   if(IS_PATTERN_USAGE(1) && ConditionForPattern1(idx)) result=m_pattern_1;      // señal número 1
   //--- si se utiliza el modelo 2, compruebe la condición para el patrón 2
   if(IS_PATTERN_USAGE(2) && ConditionForPattern2(idx)) result=m_pattern_2;      // señal número 2
//--- devuelve el resultado
   return(result);
  }

Entonces encontramos

int CExpertSignal::Direction()
  {
   ...
   int result=LongCondition()-ShortCondition();
   ...
  }

cuyo resultado se comprueba con signal.m_threshold_open y signal.m_threshold_close en

  1. bool CExpertSignal::CheckOpenLong(...),
  2. bool CExpertSignal::CheckOpenShort(...),
  3. bool CExpertSignal::CheckCloseLong(...),
  4. bool CExpertSignal::CheckCloseShort(...),
  5. bool CExpertSignal::CheckReverseLong(...), y
  6. bool CExpertSignal::CheckReverseShort(...).

Los parámetros que especifican los niveles para entrar en el mercado y fijar los precios de stop loss y take profit serían entonces devueltos por

//+------------------------------------------------------------------+
//| Detectar los niveles para comprar|
//+------------------------------------------------------------------+
bool CExpertSignal::OpenLongParams(double &price,double &sl,double &tp,datetime &expiration)
  {
  }
//+------------------------------------------------------------------+
//| Detección de los niveles de venta|
//+------------------------------------------------------------------+
bool CExpertSignal::OpenShortParams(double &price,double &sl,double &tp,datetime &expiration)
  {
  }

que son invocados por la implementación estándar de bool CExpertSignal::CheckOpenLong(...) y bool CExpertSignal::CheckOpenShort(...) tal y como se definen en la clase base. Por tanto, debería bastar con sobrecargar

  1. int CExpertSignal::LongCondition(...),
  2. int CExpertSignal::ShortCondition(...),
  3. bool CExpertSignal::OpenLongParams(...),
  4. bool CExpertSignal::OpenShortParams(...),
  5. bool CExpertSignal::CloseLongParams(...), y
  6. bool CExpertSignal::CloseShortParams(...)

para definir una nueva señal arbitraria. Tenga en cuenta que CExpertTrade contiene el código para detectar si el precio de entrada deseado está demasiado lejos del precio actual para colocar órdenes de mercado y utiliza la elección del precio de entrada para decidir automáticamente si colocar una orden stop o limitada.

Sin embargo, si el rango de negociación se define como la región entre el máximo más alto (HH) y el mínimo más bajo (LL) de las últimas n barras, entonces la condición LL < precio < HH es siempre verdadera. Por lo tanto, tanto int CExpertSignal::LongCondition(...) como int CExpertSignal::ShortCondition(...) deberían detectar siempre el patrón 0 "break out" y sea cual sea el valor que asociemos a este patrón la función int CExpertSignal::Direction() ¡siempre devolverá cero!

El enfoque natural de sobrecargar

  1. bool CExpertSignal::CheckOpenLong(...) y
  2. bool CExpertSignal::ComprobarAbrirCorto(...)

de forma que el primero comprueba

  1. LongCondition()>m_threshold_open y la segunda comprueba
  2. ShortCondition()>m_threshold_open

en lugar de

  1. m_dirección>=m_umbral_abierto y
  2. -m_direction>=m_threshold_open

no se ha podido convertir en una versión satisfactoria, todavía. Como se ha señalado, sería sencillo hacer que bool CExpertSignal::OpenLongParams(...) devolviera el precio de entrada HH y que bool CExpertSignal::OpenShortParams(...)devolviera el precio de entrada LL para completar la señal generando continuamente 2 órdenes stop.

Desde mi punto de vista es deseable tener un ejemplo que muestre como implementar esta estrategia estándar de break out en términos de la librería estándar y haciéndola lo suficientemente flexible proporcionando el patrón alternativo "break in" que resulta en órdenes limitadas en LL y HH. Obviamente, una señal de este tipo combinaría las estrategias

  1. comprar alto y vender más alto o vender bajo y comprar más bajo, así como la alternativa
  2. comprar bajo y vender alto o vender alto y comprar bajo.

proporcionándolas como patrones. Estaré extremadamente agradecido por la ayuda para terminar este enfoque.

 
AnonymousTrades:

Hola a todos,

Me pregunto cómo crear un descendiente de CExpertSignal con los dos patrones "break out" y "break in" de un rango de negociación observado utilizando el enfoque propuesto aquí, así como en Exploring Trading Strategy Classes of the Standard Library - Customizing Strategie de Harvester. Mi percepción es que cada clase de señal podría (debería) ser implementada sobrecargando las dos funciones

int CSignalBreakOutOrIn::LongCondition()  { if(IS_PATTERN_USAGE(X) && LongConditionForPatternX(idx)) return(m_pattern_X); }
int CSignalBreakOutOrIn::ShortCondition() { if(IS_PATTERN_USAGE(X) && ShortConditionForPatternX(idx)) return(m_pattern_X); }

Tenga en cuenta que CExpertTrade contiene el código para detectar si el precio de entrada deseado está demasiado lejos del precio actual para colocar órdenes de mercado y utiliza la elección del precio de entrada para decidir automáticamente si colocar una orden stop o limitada.

[...]

En mi opinión, es deseable tener un ejemplo que muestre cómo implementar esta estrategia de ruptura estándar en términos de la biblioteca estándar y hacerla lo suficientemente flexible proporcionando el patrón alternativo "break in" que resulta en órdenes limitadas en LL y HH. Estaré extremadamente agradecido por la ayuda para terminar este enfoque.


He decidido reformular mis preocupaciones para que se entiendan lo más fácilmente posible. En mi opinión, los dos artículos

  1. MQL5 Wizard: Cómo crear un módulo de señales de trading (este) y
  2. Explorando las Clases de Estrategias de Trading de la Librería Estándar - Personalizando Estrategias por Harvester Trading

demuestran en general cómo escribir nuestras propias clases de señales de la forma más sencilla. Voy a resumir esta percepción mía a continuación.

Sin embargo, todavía necesito una idea para terminar la implementación de una señal que utilice este enfoque para proponer comprar/vender cuando el precio sea más alto/bajo que el precio más alto/más bajo observado durante los últimos n periodos. Esto se supone que resulta en la colocación de un par de órdenes stop por encima y por debajo del precio actual. Ya he intentado conseguirlo sustituyendo la condición

  • Dirección()>=m_umbral_abierto por
  • LongCondition()>=m_threshold_open, por ejemplo,

pero sigue sin funcionar. Esto no tiene ningún sentido para mí porque también sobrecargué las funciones OpenLongParams(...) y OpenShortParams(...). Determinan los niveles en los que colocar las órdenes stop deseadas. ¿Podría alguien con más conocimiento de las ideas de los desarrolladores de MetaQuotes explicar cómo habrían implementado esta estrategia de ruptura más básica?

Dado que el código fuente es a menudo visto como la mejor documentación de cualquier software he pasado algún tiempo en el análisis de la clase CExpertSignal en MQL5\Include\Expert\ExpertSignal.mqh

Mi resultado fue que las funciones que comprueban las condiciones de trading se reducen esencialmente a comprobar el valor de la función Direction() { return(LongCondition()-ShortCondition()); } como sigue:

bool CExpertSignal::CheckOpenLong(...)     { if(Direction()>=m_threshold_open && OpenLongParams(price,sl,tp,expiration)) return(true); return(false); }
bool CExpertSignal::CheckOpenShort(...)    { if(-Direction()>=m_threshold_open && OpenShortParams(price,sl,tp,expiration)) return(true); return(false); }
bool CExpertSignal::CheckCloseLong(...)    { if(-Direction()>=m_threshold_close && CloseLongParams(price,sl,tp,expiration)) return(true); return(false); }
bool CExpertSignal::CheckCloseShort(...)   { if(Direction()>=m_threshold_close && CloseShortParams(price,sl,tp,expiration)) return(true); return(false); }
bool CExpertSignal::CheckReverseLong(...)  { if(!CheckCloseLong(c_price) || !CheckOpenShort(price,sl,tp,expiration)) return(false); return(true); }
bool CExpertSignal::CheckReverseShort(...) { if(!CheckCloseShort(c_price) || !CheckOpenLong(price,sl,tp,expiration)) return(false); return(true); }

(He quitado algo de código que sólo parece necesario para una ejecución estable sin contribuir a la funcionalidad de ninguna manera).

Este resumen muestra que para cualquier clase de estrategia personalizada debería ser suficiente sobrecargar las funciones

  1. int CExpertSignal::LongCondition(...),
  2. int CExpertSignal::ShortCondition(...),
  3. bool CExpertSignal::OpenLongParams(...),
  4. bool CExpertSignal::OpenShortParams(...),
  5. bool CExpertSignal::CloseLongParams(...), y
  6. bool CExpertSignal::CloseShortParams(...)

y en el artículo 2. de Harvester enlazado más arriba se explica cómo utilizar la macro IS_PATTERN_USAGE(x) en las dos primeras de forma que la señal resultante detecte varios patrones predefinidos.

Veo este problema: La condición de si el precio está entre el máximo más alto y el mínimo más bajo de las últimas n barras debe ser siempre verdadera. Por lo tanto, tanto LongCondition(...) como ShortCondition(...) devuelven el mismo valor asociado al patrón para la operativa de ruptura y el valor de Direction() es necesariamente cero a menos que se cambien las condiciones en CheckOpenLong(...) y CheckOpenShort(...).

Pero, ¿por qué no es suficiente utilizar LongCondition()>=m_threshold_open y ShortCondition()>=m_threshold_open ?

 
yankai0219:

cuando uso el archivo que adjuntaste al articulo,hay algo mal.

Me parece que el comentario sobre Tipo debería ser el siguiente:

//| Type=SignalAdvanced                                          |

Gracias por su mensaje. Su mensaje ha resuelto mi problema. Gracias.

George

 

Hola,

Cuando compilé el código, obtuve tres advertencias

declaración de 'm_open' oculta miembro samplesignal.mqh 42 23

la declaración de 'm_close' oculta el miembro samplesignal.mqh 43 23

la declaración de 'm_expiration' oculta al miembro samplesignal.mqh 52 23


m_open y m_close fueron definidos en ExpertBase.mqh pero con diferente tipo.

m_expiratin fue definido en ExpertSignal.mqh.

Comentar las tres líneas anteriores. Las advertencias han desaparecido.

George

 
Si es posible reescribir el código exacto, completo y ejecutable de este programa y corregir sus errores y ponerlo aquí
 
touhid Qolizadeh #:
Si es posible reescribir el código exacto, completo y ejecutable de este programa y corregir sus errores y ponerlo aquí.

¡Aquí lo tienes!

Saludos, Zarik

Archivos adjuntos: