Discusión sobre el artículo "Desarrollamos un Asesor Experto multidivisas (Parte 2): Transición a posiciones virtuales de estrategias comerciales" - página 5

[Eliminado]  
mytarmailS #:
No es un hecho que en el mercado la complicación del modelo funcionará mejor que una cesta de TSs simples
Bueno, es necesario no beber cada TS al comedero, sino simplemente añadir nuevas TS después de varias pasadas del optimizador.
 
Maxim Dmitrievsky "bagging" (cesta) de estrategias, sino "boosting". Esto es cuando una estrategia se optimiza en primer lugar, a continuación, sus señales se sustituyen como un parámetro para la segunda estrategia, la segunda estrategia se optimiza, y así sucesivamente.

Me parece que la aplicación de los destacados es una tarea no trivial. Normalmente, los parámetros de la estrategia se fijan al principio, y las señales de apertura/cierre se determinan mediante algún algoritmo mientras la estrategia se está ejecutando. Si guardamos el historial de aperturas de alguna forma unificada, entonces todo ello tendrá que ser alimentado a la entrada de la segunda estrategia.... ¿Es así? Si damos esta información en forma de un algoritmo (función) y sus parámetros fijos, ¿no resultará que hemos llegado al mismo embolsamiento, pero con una puerta trasera?

 

Muchas gracias, lo he leído con interés. Quiero hacer algo parecido, sólo que con más automatización, para lo cual pienso poner en funcionamiento sin piedad tus librerías para trabajar con ficheros *.opt y *.tst del tester.

[Eliminado]  
Yuriy Bykov #:

Me parece que la implementación del resaltado es una tarea no trivial. Por lo general, los parámetros de la estrategia se establecen en el arranque, y las señales de apertura/cierre se determinan mediante algún algoritmo mientras la estrategia se está ejecutando. Si guardamos el historial de aperturas en alguna forma unificada, entonces todo ello tendrá que ser alimentado a la entrada de la segunda estrategia.... ¿Es así? Si damos esta información en forma de un algoritmo (función) y sus parámetros fijos, ¿no resultará que hemos llegado al mismo embolsamiento, pero con una puerta trasera?

No he pensado en cómo hacerlo a través del optimizador. No, debería resultar que cada estrategia siguiente mejorará la anterior, es decir, construirá sobre ella. Cómo visualizarlo exactamente es cuestión de tiempo. Basta con que busques en Internet cómo funcionan los árboles potenciados y los utilices como base para tu diseño. Puede haber muchos matices, sí. Pero no lo haré yo, porque todo esto ya está en los algoritmos de MO. Y no es una panacea, pero puede ser mejor que una cartera TC en cuanto a sus propiedades.

 
Maxim Dmitrievsky #:

No había pensado en cómo hacerlo a través del optimizador.

Esta es una rutina que puede ser totalmente automatizada mediante la conexión de la mqh apropiado para mq5.


El algoritmo es el siguiente.

  1. La carpeta contiene pasadas anteriores (si no hubo pasadas - vacía) en forma de archivos.
  2. Se inicia una nueva optimización: se negocia la propia TS + se añade la negociación del punto 1. En este caso MM se distribuye uniformemente entre p.1 y TS.
  3. El mejor pase (OnTester de cualquier tipo) de la optimización se registra en el punto 1.
  4. En p.2. tantas veces como quiera la TS en la cartera.

Así que se puede mezclar lo que se quiera. Es obvio que incluso con una búsqueda completa, el resultado final dependerá de la secuencia en la que se lancen las TS.

También está claro que incluso en la SB habrá una mejora de los indicadores con cada pasada, pero será un ajuste.

 
Yuriy Bykov #:

Muchas gracias, he mirado el código. Miraré de pasar parámetros de entrada más adelante. Si no funciona para tomar este enfoque por completo, algunos puntos es probable que sea muy útil.

He aplicado los resultados actuales de mi trabajo con las entradas de nuevo (en el apéndice) al código de este artículo.

He aquí un ejemplo de lo que SimpleVolumesExpertSingle.mq5 se ha convertido.

#define  INPUT_STRUCT_ADDON
#include "Advisor.mqh"
#include "SimpleVolumesStrategy.mqh"
#include "VolumeReceiver.mqh"

input string      symbol_              = "EURGBP";    // Instrumento de negociación (símbolo)
input group "=== Parámetros del asesor."
input ulong       magic_              = 27181; // Magia

CAdvisor     *expert;         // Puntero al objeto experto

//+------------------------------------------------------------------+
//| Función de inicialización experta|
//+------------------------------------------------------------------+
int OnInit() {
   expert = new CAdvisor(new CVolumeReceiver(magic_));

   // Añadir una instancia de la estrategia
   expert.Add(new CSimpleVolumesStrategy( symbol_, inStrategyInput + inSimpleVolumesStrategyInput));

   return(INIT_SUCCEEDED);
}


Me las arreglé para lograr una prescripción única de entradas(SimpleVolumesStrategyInput.mqh) en el código.

// https://www.mql5.com/es/code/47932
// Usa esta cadena para encontrar todas las Entradas mqh.
// #include <fxsaber\Input_Struct\Input_Struct.mqh> // Original

#define  TYPENAME_INPUT SimpleVolumesStrategyInput

#define  MACROS_MULTI                    \
  MACROS(signalPeriod, int, 13)         \ // Número de velas para promediar el volumen
  MACROS(signalDeviation, double, 0.3)  \ // Desviación relativa de la media para la apertura de la primera orden
  MACROS(signaAddlDeviation, double, 1) \ // Desviación relativa de la media en la apertura de la segunda orden y siguientes
  MACROS(openDistance, int, 0)          \ // Distancia del precio a la orden pendiente
  MACROS(stopLevel, double, 10500)      \ // Stop Loss (en puntos)
  MACROS(takeLevel, double, 465)        \ // Take Profit (en pips)
  MACROS(ordersExpiration, int, 1000)   \ // Hora de vencimiento de las órdenes pendientes (en minutos)
  MACROS(maxCountOfOrders, int, 3)        // Número máximo de órdenes abiertas simultáneamente

Archivos adjuntos:
 
fxsaber #:

He vuelto a aplicar los resultados actuales de mi trabajo con las entradas (en el apéndice) al código de este artículo.

Un ejemplo de lo que SimpleVolumesExpertSingle.mq5 se ha convertido.


He conseguido una única entrada de inputs(SimpleVolumesStrategyInput.mqh) en el código.

Me pareció de alguna manera notablemente más fácil que la variante anterior. Aunque, tal vez es sólo que cuando se mira el código de otra persona una vez más, se hace más claro y más simple cada vez. Muchas gracias. Mientras estudiaba, me surgió una duda, ¿no se puede colocar el código que viene después de "// Copy-Paste update from here:" en un archivo include y adjuntarlo en lugar de pegarlo? No es conveniente experimentar ahora mismo, así que se me ocurrió preguntar.

En el tercer artículo aún no he llegado a los parámetros de entrada :(. Pero seguro que llegará.

 
Yuriy Bykov #:

Mientras estudiaba, me surgió una duda, ¿es posible colocar el código que viene después de "// Copy-Paste update from here:" en un archivo include y conectarlo en lugar de pegarlo? No es conveniente experimentar ahora mismo, así que decidí preguntar.

Desafortunadamente, no se puede, porque #include del mismo archivo sólo ocurre una vez - el primer encuentro. Después de eso se ignora.

Esta es una de las razones por las que tuvo que hacer un archivo completamente idéntico con un nombre diferente aquí.


Pero en general, la opción Copiar-Pegar es un par de clics. La comprensión de que el código no es necesario.

PriceChannel
PriceChannel
  • www.mql5.com
Ценовой канал произвольной длительности (таймфрейм) бара.
 
Yuriy Bykov #:

En el tercer artículo, los parámetros de entrada aún no han llegado :(. Pero llegará seguro.

Tu arquitectura es algo diferente a la mia, asi que no he dotado a INPUT_STRUCT de muchas cosas que serian utiles en este proyecto.

Es bueno que no lo publicaras, porque lo he rehecho de nuevo - a la versión más concisa y conveniente (parece ser la definitiva).

He añadido grupo, string-inputs y algunas otras pequeñas cosas para mayor comodidad en el futuro.

#define  TYPENAME_INPUT StrategyInput

#define  MACROS_MULTI                           \
  INPUT(symbol, string, "EURGBP")              \ // Instrumento de negociación (símbolo)
  INPUT(timeframe, ENUM_TIMEFRAMES, PERIOD_H1) \ // Periodo del gráfico (timeframe)
  GROUP("=== Opciones de gestión del capital") \
  INPUT(fixedLot, double, 0.01)                  // Tamaño de las posiciones abiertas (fijo)
#define  TYPENAME_INPUT SimpleVolumesStrategyInput

#define  MACROS_MULTI                           \
  GROUP("=== Parámetros de la señal de apertura")   \
  INPUT(signalPeriod, int, 13)                 \ // Número de velas para promediar el volumen
  INPUT(signalDeviation, double, 0.3)          \ // Desviación relativa de la media para la apertura de la primera orden
  INPUT(signaAddlDeviation, double, 1)         \ // Desviación relativa de la media en la apertura de la segunda orden y siguientes
  GROUP("=== Parámetros de órdenes pendientes.")   \
  INPUT(openDistance, int, 0)                  \ // Distancia del precio a la orden pendiente
  INPUT(stopLevel, double, 10500)              \ // Stop Loss (en puntos)
  INPUT(takeLevel, double, 465)                \ // Take Profit (en pips)
  INPUT(ordersExpiration, int, 1000)           \ // Hora de vencimiento de las órdenes pendientes (en minutos)
  GROUP("=== Opciones de gestión del capital") \
  INPUT(maxCountOfOrders, int, 3)                // Número máximo de órdenes abiertas simultáneamente


Trozos de código de la aplicación para demostrar cómo se utiliza.

#define  INPUT_STRUCT_ADDON
#include "Advisor.mqh"
#include "SimpleVolumesStrategy.mqh"
#include "VolumeReceiver.mqh"

input group "=== Parámetros del asesor."
input ulong       magic_              = 27181; // Magia

CAdvisor     *expert;         // Puntero al objeto experto

//+------------------------------------------------------------------+
//| Función de inicialización experta|
//+------------------------------------------------------------------+
int OnInit() {
   expert = new CAdvisor(new CVolumeReceiver(magic_));

   // Añadir una instancia de la estrategia
   expert.Add(new CSimpleVolumesStrategy(inStrategyInput + inSimpleVolumesStrategyInput));

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Constructor|
//+------------------------------------------------------------------+
CSimpleVolumesStrategy::CSimpleVolumesStrategy( const string sInputs ) : CStrategy(sInputs)
{
   this.Input = sInputs;

   ArrayResize(m_orders, this.Input.maxCountOfOrders);

   // Cargar el indicador para obtener volúmenes de ticks
   iVolumesHandle = iVolumes(this.InputStrategy.symbol, this.InputStrategy.timeframe, VOLUME_TICK);

// Establecer el tamaño del array-receptor de volúmenes tick y el direccionamiento requerido
   ArrayResize(volumes, this.Input.signalPeriod);
   ArraySetAsSeries(volumes, true);
}
//+------------------------------------------------------------------+
//|| Constructor|
//+------------------------------------------------------------------+
CStrategy::CStrategy( const string sInputs ) : m_isChanged(false)
{
  this.InputStrategy = sInputs;
}
//+------------------------------------------------------------------+
//| Función de inicialización experta|
//+------------------------------------------------------------------+
int OnInit() {
// Comprobar si los parámetros son correctos
   if(startIndex_ < 0 || startIndex_ + totalStrategies_ > 9) {
      return INIT_PARAMETERS_INCORRECT;
   }

// Crear y rellenar un array de instancias de estrategia
   CStrategy *strategies[9];

   StrategyInput InputBase;
   SimpleVolumesStrategyInput Input;

   InputBase.timeframe = PERIOD_H1;

   // La primera forma de configuración es a través de la inicialización.
   const StrategyInput InputBase0 = {"EURGBP", PERIOD_H1, NormalizeDouble(0.01 / 0.16 * depoPart_, 2)};
   const SimpleVolumesStrategyInput Input0 = {13, 0.3, 1.0, 0, 10500, 465, 1000, 3};
   strategies[0] = new CSimpleVolumesStrategy(InputBase0 + Input0);

   // La segunda forma de especificar es mediante string y array.
   InputBase.fixedLot = NormalizeDouble(0.01 / 0.09 * depoPart_, 2);
   const double Array1[] = {17, 1.7, 0.5, 0, 16500, 220, 1000, 3};
   strategies[1] = new CSimpleVolumesStrategy(InputBase["symbol = EURGBP"] + "," + Input[Array1]);

   // La tercera forma de especificar es mediante la asignación de campos.
   InputBase.fixedLot = NormalizeDouble(0.01 / 0.16 * depoPart_, 2);
   InputBase.symbol = "EURGBP";
   const double Array2[] = {51, 0.5, 1.1, 0, 19500, 370, 22000, 3};
   strategies[2] = new CSimpleVolumesStrategy(InputBase + Input[Array2]);
Archivos adjuntos:
 
fxsaber #:

Menos mal que no lo publicaron, porque lo he vuelto a hacer, a la versión más concisa y fácil de usar (parece que es la definitiva).

Sí, una situación muy familiar. Todo parece estar ahí, y luego lo rehaces y queda aún mejor. Creo que esta tampoco es la versión final, porque te orientaste en aquellos escenarios de uso de parámetros en código que ya han sido publicados. En lo que respecta a la construcción de parámetros en conjuntos, y más aún a la construcción automática en conjuntos, probablemente encontrarás que puedes mejorar/simplificar también.

¡¡¡Gracias!!!