Menos código, más acción... escribir un EA - página 4

 
Maxim Kuznetsov:
¿Por qué has quitado el post sobre el siguiente paso?

Por favor, ponga a prueba su arrogancia. Y lee las normas del recurso.

Todos podéis escribir en los mensajes del foro y en la descripción en KodoBaz.

 
Maxim Kuznetsov:
¿Por qué has quitado el post sobre el siguiente paso?

Vi el post, no vi nada criminal. Supongo que no estaba buscando lo suficiente.

 
Maxim Kuznetsov:

Por supuesto que el balance está bajando. ¿Qué esperas de "dos MAs que se cruzan"?


Puede tomar una base diferente para el EA - las MAs están lejos de ser la mejor opción.

 
aleger:

Puede tomar una base diferente para el EA - mashki está lejos de ser la mejor opción.

Si te fijas un poco más, te darás cuenta de que ya puedes implementar bastantes cosas :-)

Así que resulta lo siguiente:

* el programador de la aplicación (usuario de la biblioteca) declaró que tiene una micro-excel con varias columnas (en el caso de uso son FAST_MA,SLOW_MA,SIGNAL_BUY,SIGNAL_SELL)

* y esbozó una función cómo sabe calcular las celdas individuales. En el ejemplo se refería a iMA.

* al mismo tiempo puede acceder libremente a otras celdas de esta tabla (DataFrame romperá las secuencias si es posible)

* y por separado el usuario escribió la función "comprobar los valores de la fila y si es el momento de operar"

Obviamente, esto es suficiente para que el EA comience a operar. Además, la estrategia puede modificarse de forma muy flexible: cualquier cosa que se le ocurra como cálculo de una tabla es posible.
La otra cosa es que esto es sólo el primer medio paso :-) hasta ahora, el EA está operando como el mono-cambiador, sólo con el lote mínimo, en un símbolo y de un marco de tiempo.

 

En las dos primeras partes, obtuvimos un Asesor Experto que puede ejecutar las estrategias más sencillas, que se describen como "monos o flips por señal".
Las señales en sí se programan de forma muy sencilla, casi como en Excel :-)

Es hora de enseñar un poco más al Asesor Experto. Por lo menos pon StopLoss y rastrea.

Completar la descripción artística de la estrategia con la frase "El Stop Loss se coloca en la distancia STOPLOSS_POINTS y se arrastra por los fractales". También introducimos cambios en el caso de uso descrito anteriormente:

  • nueva entrada de parámetros de EA int STOPLOSS_POINTS=100;
  • añadir dos campos calculados UPPER_FRACTAL,LOWER_FRACTAL en ENUM_SERIES
  • y en la función GetData añadir dos "case:" para calcularlos

y proporcionar al usuario una función (método de la clase EA), para configurar el EA. La entrada más sencilla puede verse como

SetStopLoss(STOPLOSS_POINTS,LOWER_FRACTAL,UPPER_FRACTAL);

dice "establece el Stop Loss a una distancia especificada, y arrastra la compra por la columna LOWER_FRACTAL,la venta por UPPER_FRACTAL"; creo que el método tiene un nombre obvio y su sintaxis es más o menos clara.

El usuario hipotético hizo muchos gestos (declaró la entrada, añadió dos columnas y llamó a la configuración de la función), vamos a desarrollar la biblioteca para que sus acciones conduzcan al resultado esperado. También tendremos que desarrollar cálculos tabulares y sentar las bases del mecanismo de mensajes/eventos.

En el copy-paste, se han eliminado todos los comentarios innecesarios y el código MQL5 para que sea más compacto

input ENUM_APPLIED_PRICE FAST_MA_PRICE=PRICE_CLOSE;
input ENUM_MA_METHOD FAST_MA_METHOD=MODE_EMA;
input int FAST_MA_PERIOD=14;
input int FAST_MA_SHIFT=0;

input ENUM_APPLIED_PRICE SLOW_MA_PRICE=PRICE_CLOSE;
input ENUM_MA_METHOD SLOW_MA_METHOD=MODE_SMA;
input int SLOW_MA_PERIOD=54;
input int SLOW_MA_SHIFT=0;

// начальные значения StopLoss, TakeProfit
input int STOPLOSS_POINTS=100;
input int TAKEPROFIT_POINTS=200;

#include "EA/EA.mqh"

enum ENUM_SERIES {
   FAST_MA,       // id. значений FAST_MA
   SLOW_MA,       // id. значений SLOW_MA 
   SIGNAL_BUY,    // сигнал к покупкам
   SIGNAL_SELL,   // сигнал к продажам
   UPPER_FRACTAL,       // верхний фрактал (для трала стопов ордеров sell)
   LOWER_FRACTAL, // нижний фрактал
   TOTAL_SERIES   // последний элемент перечисления = кол-во элементов
};

double GetData(EA *ea,int id,int shift,DataFrame *table)
{
   switch ((ENUM_SERIES)id) {
      case FAST_MA:
         return table[FAST_MA][shift]=iMA(ea.Symbol,ea.Period,FAST_MA_PERIOD,0,FAST_MA_METHOD,FAST_MA_PRICE,shift);
      case SLOW_MA:
         return table[SLOW_MA][shift]=iMA(ea.Symbol,ea.Period,SLOW_MA_PERIOD,0,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);
      case SIGNAL_BUY:
         return table[SIGNAL_BUY][shift]=table.CrossedUp(FAST_MA,SLOW_MA,shift);
      break;
      case SIGNAL_SELL:
         return table[SIGNAL_SELL][shift]=table.CrossedDn(FAST_MA,SLOW_MA,shift);
      break;
      // Расчёт уровней трала
      case UPPER_FRACTAL:
         // верхний фрактал. уровень по которому тралятся sell
         return table[UPPER_FRACTAL][shift]=iFractal(ea.Symbol,ea.Period,MODE_UPPER,shift+2);
      case LOWER_FRACTAL:
         return table[UPPER_FRACTAL][shift]=iFractal(ea.Symbol,ea.Period,MODE_LOWER,shift+2);
   }
   return EMPTY_VALUE;
}
int SignalOfCross(EA *ea,int shift,DataFrame *data)
{
   if (FAST_MA_PRICE!=PRICE_OPEN || SLOW_MA_PRICE!=PRICE_OPEN) shift++;
   if (data[SIGNAL_BUY][shift]==1.0)  return OP_BUY;
   if (data[SIGNAL_SELL][shift]==1.0) return OP_SELL;
   return -1;
}
EA *ea=NULL;

int OnInit()
{
   ea = new EA();
   ea.SetupTimeframe(_Symbol,_Period,TOTAL_SERIES,30,GetData);
   ea.SetupSignal(SignalOfCross);

        // укажем начальный стоп-лосс ордеров и уровни для тралов 
   ea.SetupStopLoss(STOPLOSS_POINTS,LOWER_FRACTAL,UPPER_FRACTAL);
   // и заодно тейк-профит
   ea.SetupTakeProfit(TAKEPROFIT_POINTS);
   // остальная часть одинакова для всех советников
   //................
}


 
Maxim Kuznetsov:

Ya es difícil mirar el código así. Escribir de forma sencilla es una tarea difícil. La concisión es importante, pero incluso con ella, la simplicidad puede escaparse fácilmente.

Tu opinión sobre tu código, como mi opinión sobre el mío, es muy subjetiva. Los observadores desde fuera pueden decir de forma mucho más objetiva si es complicado o simple.

Como observador de su código - complicado.

 
fxsaber:

Ya es difícil mirar el código así. Escribir de forma sencilla es una tarea difícil. La concisión es importante, pero incluso con ella, la simplicidad puede escaparse fácilmente.

Tu opinión sobre tu código, como mi opinión sobre el mío, es muy subjetiva. Los observadores desde fuera pueden decir de forma mucho más objetiva si es complicado o simple.

Como observador de su código - complicado.

Sugiere una entrada más clara y concisa sólo para el caso de uso. O ediciones de la actual.

Este es el punto más difícil - y es el que más se ofrece para la discusión.




 
Maxim Kuznetsov:

Han sugerido una notación más lúcida y concisa sólo para casos de uso. O ediciones de la actual.

Este es el punto más difícil, y justo el que más se propone para el debate.

No voy a sugerirlo, ya que no sé y ni siquiera entiendo por qué es necesario. MQL4 difícilmente será más sencillo que MQL4 para un observador externo. Los desarrolladores de MQL4 han dado brillantemente con una arquitectura sencilla.

 

¿Qué quieres conseguir con ello? Para ser sincero, no lo entiendo. Al principio pensé que se pretendía un marco de trabajo, pero no, no hay clases envolventes para indicadores, órdenes, algoritmos estándar de toma de decisiones, nada. Aunque es mucho más legible esta construcción: fast.Get(2)>=slow.Get(1); (es sólo por el ejemplo), pero la declaración:

CMA fast=nuevo CMA(NULL,0,12,...);

CMA slow=nuevo CMA(NULL,0,100,...);

Esto es algo que podemos discutir, mientras tú, IMHO, estás pisando fuerte.

 
fxsaber:

Como observador de su código - difícil.

Estoy de acuerdo, es muy difícil leer su código, incluso si se conoce el lenguaje.