English Русский 中文 Deutsch 日本語 Português
Método de las áreas

Método de las áreas

MetaTrader 5Sistemas comerciales | 11 marzo 2016, 14:35
1 358 0
Vladimir Karputov
Vladimir Karputov

Índice


Introducción

Cómo instalar correctamente los indicadores y asesores desde los archivos al final del artículo: los archivos "Indicators.zip" y "Experts.zip" deben ser descomprimidos en el <catálogo de datos>\MQL5\

La descripción del método de las áreas fue publicada por primera vez en 2004 [1]. El método es interesante por su enfoque inusual de los datos del indicador RSI: en él mismo se propone valorar el área que dibuja el oscilador por encima/debajo de la línea 50 a partir del momento de su último cruce. Desde el año 2004 los mercados han cambiado mucho, se ha creado el lenguaje MQL5, y eso significa que ha llegado el momento de comprobar la estrategia en MQL5 y en el mercado actual.


1. Metodología comúnmente aceptada de la valoración de los índices del indicador RSI

El método habitual de comercio con las señales de RSI implica la valoración de los datos del indicador sobre la sobrecompra/sobreventa, la búsqueda de divergencias entre los datos del indicador y el precio, el viraje después de que el indicador visite las zonas de sobrecompra/sobreventa, la amplitud fallida. De esta forma, para el análisis técnico del oscilador RSI se usan un mínimo de cuatro canales, y esto complica el sistema de toma de decisiones.

Además, sabemos que el indicador RSI no puede encontrarse en la zona de sobrecompra (por encima de la línea 70)/sobreventa (por debajo de la línea 30) por mucho tiempo, regresa obligatoriamente y cruza la línea media 50:

RSI

Fig. 1. El oscilador RSI siempre regresa desde las zonas de sobrecompra/sobreventa

La figura 1 muestra que el tiempo total que el oscilador se encuentra en las áreas de sobrecompra/sobreventa en comparación con el resto del tiempo, es muy poco. También, después de visitar las zonas de sobrecompra/sobreventa RSI cruza la línea media 50. Precisamente el conocimiento de que el oscilador RSI regresará y cruzará la línea 50, así como la necesidad de simplificar el análisis técnico de los datos del oscilador RSI se han convertido en la base para el desarrollo del método de las áreas.


2. Método de las áreas

El método de las áreas propone valorar los datos del oscilador RSI según un índice: el área que ha formado el oscilador por encima/debajo de la línea 50. Precisamente esta magnitud definirá el grado de sobrecompra/sobreventa:

area_figure

Fig. 2. Método de las áreas, valoración del área por encima/debajo de la línea 50

La señal de apertura de la posición, en este caso, es la magnitud del área por encima/debajo de la línea 50 a partir del momento en que el indicador RSI la cruzó por última vez.   

  • Si RSI se encuentra mucho tiempo por encima de la línea 50 y tras superar una determinada magnitud del área (supongamos que sea un valor de área igual a 300) se abrirá la posición SELL: 

SELL signal 

Fig. 3. Señal de apertura de una posición SELL en cuanto el área sea igual a 300

  • Respectivamente, si RSI se encuentra mucho tiempo por debajo de la línea 50 después de superar una deteminada magnitud, se abrirá una posición BUY.

Servirá como señal de cierre de posición el cruce del oscilador RSI de la línea 50 con la subsecuente formación de un máximo/mínimo local y un retroceso con respecto a él con una magnitud del 4% de la escala.

  • Por ejemplo, después de encontrarse mucho tiempo sobre la línea 50, en un cierto momento, tenemos una posición SELL abierta. A continuación, el valor del indicador comienza a disminuir y alcanza, supongamos, la línea 40, después de lo cual, el valor del indicador comienza a aumentar (es decir, se forma un mínimo local). Cuando el valor del indicador alcance la línea 44, esta será precisamente la señal para el cierre de posición: 

Close SELL signal 

Fig. 4. Señal de cierre de la posición SELL después de formarse el mínimo local y el subsiguiente retroceso del 4%

  • Una lógica análoga tendremos cuando el indicador se encuentre durante un periodo largo bajo la línea 50, solo que en este caso, esperamos la formación de un máximo local.

El indicador RSIAreaIndicator nos ayudará a visualizar el área por encima/debajo de la línea 50.  


3. Indicador RSIAreaIndicator_v1

El indicador RSIAreaIndicator está construido en base al oscilador RSI. La diferencia principal consiste en que el indicador RSIAreaIndicator tiene dos búferes. Uno de los búferes tiene el estilo de construcción de DRAW_HISTOGRAM, y el segundo, el de DRAW_LINE. Los valores de los búferes se obtienen con la fórmula

formula RSIAreaIndicaor

Aspecto del indicador RSIAreaIndicator version 1.00:

RSIAreaIndicator 

Fig. 5. Indicador RSIAreaIndicator _v1

 

3.1. Crear una plantilla del indicador 

Le recomiendo que ubique los indicadores de usuario creados por usted en una carpeta aparte. En mi caso, esta carpeta se llama "MyInd". Para comenzar a escribir el indicador, hay que crear su plantilla en el editor de código MetaEditor usando el asistente MQL5 Wizard. He reunido los primeros pasos de la creación de la plantilla en este vídeo:


Podrá echar un vistazo a la plantilla obtenida al final del artículo: el indicador está guardado con el nombre "RSIAreaIndicatorStep1.mq5". 

3.2. Rellenar los "encabezamientos" del indicador

El siguiente paso es añadir la descripción del indicador. Posteriormente, siempre se podrá ver en las propiedades del indicador en la pestaña "General". Todo el código añadido en el artículo se destacará a color para que sea más visible:

#property version   "1.00"
#property description   "The indicator displays area RSI over/under line 50"
#property indicator_separate_window

Como podemos recordar, el indicador RSIAreaIndicator tiene dos búferes de indicador. Aparte de estos dos, necesitaremos otro más, que será auxiliar. De esta forma, en el indicador se usarán un total de tres búferes. Comencemos editando el "encabezamiento" del indicador:

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   2
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_type2   DRAW_LINE
#property indicator_color1  clrGray
#property indicator_color2  clrGray
//--- input parameters
input int      ExtRSIPeriod=13;

Ahora hay que declarar las tres matrices en las que se guardarán los valores de los búferes de indicador y del auxiliar.

//--- input parameters
input int      ExtRSIPeriod=13;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |

A continuación, dado que nuestro indicador RSIAreaIndicator se calcula en base al indicador estándar RSI y nosotros necesitaremos obtener los valores del indicador, hará falta una variable en la que se guardará el manejador del indicador Relative Strength Index:

double ExtMapBuffer3[];
//--- variable for storing the handle of the iRSI indicator 
int    handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |

Solo queda actualizar el "encabezamiento" de las tres variables de servicio. En la variable name se guardará el nombre del símbolo en el que ha sido iniciado el indicador, en la variable short_name, el nombre abreviado del indicador, y en la variable bars_calculated, la cantidad de barras calculadas en el indicador RSI:

int    handle;
//--- variable for storing 
string name=Symbol();
//--- name of the indicator on a chart 
string short_name;
//--- we will keep the number of values in the Relative Strength Index indicator 
int    bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |

El "encabezamiento" del indicador ya ha sido rellenado, ahora podemos pasar a la edición de la función OnInit().

3.3. Editar la función OnInit() del indicador 

Puesto que estamos escribiendo un indicador, necesitamos enlzar nuestros búferes de indicador con las matrices dinámicas del tipo double declaradas anteriormente:

int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,ExtMapBuffer2,INDICATOR_DATA);
   SetIndexBuffer(2,ExtMapBuffer3,INDICATOR_CALCULATIONS);
//---
   return(INIT_SUCCEEDED);

Entonces, inmediatamente después de unir los búferes y las matrices, establecemos la indexación de los elementos de la matriz como en las series temporales (recomiendo ver un buen ejemplo de la guía de ArraySetAsSeries). El elemento de las matrices que está más a la derecha, tendrá el índice "0":

   SetIndexBuffer(1,ExtMapBuffer2,INDICATOR_DATA);
   SetIndexBuffer(2,ExtMapBuffer3,INDICATOR_CALCULATIONS);
   ArraySetAsSeries(ExtMapBuffer1,true);
   ArraySetAsSeries(ExtMapBuffer2,true);
   ArraySetAsSeries(ExtMapBuffer3,true);
//---
   return(INIT_SUCCEEDED);

Ahora establecemos la precisión de representación, el indicador se representará con dos decimales después de la coma:

   ArraySetAsSeries(ExtMapBuffer3,true);
//--- set accuracy 
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//---
   return(INIT_SUCCEEDED);

 En la función OnInit() queda, además, obtener el manejador del indicador RSIndex, rellenar la variable short_name y asignarle a nuestro indicador un nombre abreviado:

   ArraySetAsSeries(ExtMapBuffer2,true);
   ArraySetAsSeries(ExtMapBuffer3,true);
//--- set accuracy 
   IndicatorSetInteger(INDICATOR_DIGITS,2);
   handle=iRSI(name,0,ExtRSIPeriod,PRICE_CLOSE);
//--- if the handle is not created 
   if(handle==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                  name,
                  EnumToString(PERIOD_CURRENT),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }
//--- show the symbol/timeframe the RSI Area Indicator is calculated for 
   short_name=StringFormat("RSIArea(%d)",ExtRSIPeriod);
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator 
   return(INIT_SUCCEEDED);

Y bien, ya hemos rellenado el "encabezamiento" del indicador y la  función OnInit(). Puede ver el código editado al final del artículo, el indicador está guardado con el nombre "RSIAreaIndicatorStep2.mq5".  

3.4. Crear la función auxiliar del indicador 

Para trabajar con el indicador RSIAreaIndicator hay que obtener los datos del indicador RSI cada vez que se entre en la función OnCalculate(). Es igualmente importante hacer posible que el código se lea de forma cómoda y dividir el funcional del programa. Por eso el código auxiliar de obtención de los valores de RSI y el copiado de estos valores a uno de los búferes de RSIAreaIndicator han sido introducidos en una función aparte FillArrayFromBuffer(). La ubicamos después de OnCalculate(). Los valores se copian con la ayuda de CopyBuffer.

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+ 
//| Filling indicator buffers from the iRSI indicator                | 
//+------------------------------------------------------------------+ 
bool FillArrayFromBuffer(double &rsi_buffer[],  // indicator buffer of Relative Strength Index values 
                         int ind_handle,        // handle of the iRSI indicator 
                         int amount             // number of copied values 
                         )
  {
//--- reset error code 
   ResetLastError();
//--- fill a part of the iRSIBuffer array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(ind_handle,0,0,amount,rsi_buffer)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iRSI indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(false);
     }
//--- everything is fine 
   return(true);
  }
//+------------------------------------------------------------------+

3.5. Creación del código principal de funcionamiento del indicador 

El código (o lógica) principal de funcionamiento del indicador RSIAreaIndicator se ubica en la función OnCalculate(). Aquí se declara la variable principal values_to_copy. Posteriormente, la variable values_to_copy almacenará el número de valores que desea copiar desde el indicador RSI.

                const int &spread[])
  {
//--- number of values copied from the iRSI indicator 
   int values_to_copy;
//--- determine the number of values calculated in the indicator 
   int calculated=BarsCalculated(handle);
   if(calculated<=0)
     {
      PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
      return(0);
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Cáculo del valor de values_to_copy:

      PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
      return(0);
     }
//--- if it is the first start of calculation of the indicator or if the number of values in the iRSI indicator changed 
//---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history) 
   if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
     {
      //--- if the iRSIBuffer array is greater than the number of values in the iRSI indicator for symbol/period, then we don't copy everything  
      //--- otherwise, we copy less than the size of indicator buffers 
      if(calculated>rates_total) values_to_copy=rates_total;
      else                       values_to_copy=calculated;
     }
   else
     {
      //--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate() 
      //--- for calculation not more than one bar is added 
      values_to_copy=(rates_total-prev_calculated)+1;
     }
//--- return value of prev_calculated for next call
   return(rates_total);

¿Por qué la variable values_to_copy se calcula así precisamente? En un indicador MQL5 los elementos de las matrices (time[], open[], high[], low[], close[], tick_volume[], volume[] y spread[]), transmitidos a la función OnCalculate(), tienen una indexación que va del principio de la matriz hacia el final. Este es el aspecto que tiene, tomando como ejemplo el gráfico:

Array Not Series

Fig. 6. Indexación de los elementos de la matriz, si la matriz no es una serie temporal 

Es decir, en una matriz que no sea una serie temporal, el elemento más a la derecha tendrá el índice máximo. Esto debe tenerse en cuenta a la hora de realizar los cálculos matemáticos.

Ahora que el valor de la variable values_to_copy ha sido calculado, se puede invocar la función auxiliar FillArrayFromBuffer() y rellenar con valores los búferes de indicador ExtMapBuffer1[]ExtMapBuffer2[]:

      //--- for calculation not more than one bar is added 
      values_to_copy=(rates_total-prev_calculated)+1;
     }
//--- fill the array with values of the iRSI indicator 
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operation 
   if(!FillArrayFromBuffer(ExtMapBuffer3,handle,values_to_copy)) return(0);
//---
   for(int i=0;i<values_to_copy;i++)
     {
      ExtMapBuffer1[i]=ExtMapBuffer2[i]=ExtMapBuffer3[i]-50.0;
     }
//--- memorize the number of values in the Relative Strength Index indicator 
   bars_calculated=calculated;
//--- return value of prev_calculated for next call
   return(rates_total);

El indicador RSIAreaIndicator version 1.00 está listo. Puede descargarlo al final del artículo, con el nombre "RSIAreaIndicatorv1.mq5". Ahora podemos proceder a escribir el asesor RSIAreaEA version 1.00, que comerciará según el métodos de las áreas.


4. Asesor RSIAreaExpert version 1.00

Al igual que en el caso de los indicadores, recomiendo ubicar los asesores creados en una carpeta aparte. Por ejemplo, mi carpeta para los asesores se llama "MyExp". Creamos la plantilla del asesor RSIAreaExpert_v1 de forma análoga al indicador. Una matización importante: en uno de los pasos hay que quitar todas las marcas de las casillas de verificación:

Setting Expert
 

 Fig. 7. Ajustes para crear el asesor

Podrá ver la plantilla obtenida al final del artículo, el asesor está guardado con el nombre "RSIAreaExpert_v1_Step1.mq5". 

4.1. Editar los "encabezamientos" del asesor

Añadimos la descripción del asesor. Será visible en la pestaña "General" del asesor:

#property version   "1.00"
#property description "EA trades on \"Method areas\""
//+------------------------------------------------------------------+
//| Expert initialization function                                   |

La descripción no es algo que siempre queramos rellenar de primeras, sin embargo, en lo sucesivo, esta regla le servirá de una vez y para siempre: "Al crear un programa, lo primero que debemos hacer es crear una descripción". 

El asesor usará la biblioteca estándar, la clase CTrade para ejecutar operaciones comerciales. Para ello será necesario conectar la clase CTrade y declarar la variable my_trade:

#property description "EA trades on \"Method areas\""
#include <Trade\Trade.mqh>
//--- global variables
CTrade      my_trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |

Asimismo, añadiremos tres variables (para guardar el manejador Relative Strength Index, para guardar el área calculada actual y una variable auxiliar):

//--- global variables
CTrade      my_trade;
int         handle;     // variable for storing the handle of the iRSI indicator 
double      RSIArea;    // the calculated area
double      RSIOpen;    // the auxiliary variable
//+------------------------------------------------------------------+
//| Expert initialization function                                   |

El último paso de la edición del "encabezamiento" del asesor es la adición de los parámetros de entrada:

double      RSIOpen;    // the auxiliary variable
//--- input parametres
input int   ExtRSIPeriod=13;    // period of RSI
input int   AreaCondition=300;  // area
input ENUM_TIMEFRAMES period=PERIOD_M15;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |

La variable period se introduce exclusivamente para que sea más cómodo realizar el test en el simulador de estrategias, de esta forma, se podrán establecer diferentes diapasones de los periodos testados:

variable period

Fig. 8. La variable period permite testar el asesor en una amplio diapasón de periodos 

Ya hemos rellenado el "encabezamiento" del asesor, ahora ha llegado el turno de la función OnInit(). En OnInit() habrá solo una operación, la obtención del manejador del indicador en el símbolo actual (Symbol()) y en el periodo establecido (period):

int OnInit()
  {
//---
   handle=iRSI(Symbol(),period,ExtRSIPeriod,PRICE_CLOSE);
//--- if the handle is not created 
   if(handle==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(period),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }

Todos estos cambios en el proceso de edición del asesor se pueden ver en el archivo "RSIAreaExpert_v1_Step2.mq5".

4.2. Función auxiliar RSIAreaFunc 

La función para determinar el área RSIAreaFunc() consta de varias partes funcionales. Vamos a ir añadiendo funcionalidades de forma paulatina. Primer bloque (daremos las aclaraciones pertinentes después del código):

void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+
//| Area calculation                                                 |
//+------------------------------------------------------------------+
double RSIAreaFunc(int &RSIAreaShift,int BeginShift)
  {
   int    shift,limit;
   double rsivalue,result;
//--- get current RSI 
   limit=Bars(Symbol(),period)-ExtRSIPeriod;
   if(limit>100)
      limit=100;
   double   arr_rsi[];
   ArrayResize(arr_rsi,limit);
   ArraySetAsSeries(arr_rsi,true);
   if(CopyBuffer(handle,0,0,limit,arr_rsi)==-1)
     {
      Print("CopyBuffer from iRSI failed, no data");
      return(0);
     }
   return(result);
  }

La variable limit es responsable de la cantidad de valores del indicador iRSI que vamos a copiar en la matriz arr_rsi[] con ayuda de CopyBuffer. Limitamos la variable limit al valor "100", es decir, copiaremos siempre los últimos 100 valores del indicador iRSI. Estos cambios en la edición del asesor los podemos ver en el archivo "RSIAreaExpert_v1_Step3.mq5".

4.3 Código de comprobación del funcionamiento CopyBuffer 

Si no comprende del todo cómo funciona la función CopyBuffer y qué valores se contienen en la matriz con el índice "0", entonces podemos escribir un sencillo código de comprobación: en la función OnTick() escribimos la invocación a la función auxiliar RSIAreaFunc().

void OnTick()
  {
//---
   static int RSIAreaShift=0;
   RSIAreaFunc(RSIAreaShift,0);
  }
//+------------------------------------------------------------------+
//| Area calculation                                                 |
//+------------------------------------------------------------------+
double RSIAreaFunc(int &RSIAreaShift,int BeginShift)

Al final del primer bloque de la función RSIAreaFunc() terminamos de escribir la muestra de comentarios, los valores de los elementos inicial y final de la matriz arr_rsi[]:

   if(CopyBuffer(handle,0,0,limit,arr_rsi)==-1)
     {
      Print("CopyBuffer from iRSI failed, no data");
      return(0);
     }
//---
   Comment("arr_rsi[",limit-1,"]=",DoubleToString(arr_rsi[limit-1],2),
           "; arr_rsi[0]=",DoubleToString(arr_rsi[0],2));
   return(result);
  }

Este código de comprobación ha sido introducido solo en el archivo RSIAreaExpert_v1_Step3_check.mq5, y no estará en el experto principal. Para realizar la comprobación, haremos lo siguiente:

  • compilar (si no se ha hecho con anterioridad) el archivo del asesor RSIAreaExpert_v1_Step3_check.mq5;
  • abrir un nuevo gráfico de cualquier instrumento y cambiar para este el marco temporal a M15 (puesto que por defecto, en los parámetros de entrada, la variable period=PERIOD_M15);
  • insertar en el gráfico el indicador RSI (menú "insertar" -> "Indicadores" -> "Osciladores" ->  "Relative Strength Index" con estos ajustes: "Perido" 13 y "Aplicar" Close);
  • conectar al gráfico el asesor RSIAreaExpert_v1_Step3_check.mq5.

En el gráfico se verá en seguida que el valor del elemento con el índice "0" en la matriz arr_rsi  corresponde al valor del indicador RSI en la barra a la derecha del todo:

  check function CopyBuffer 

Fig. 9. Comprobar el funcionamiento de la función CopyBuffer  

4.4. Continuamos la edición de la función auxiliar

Siguiente bloque de la función RSIAreaFunc():

   if(CopyBuffer(handle,0,0,limit,arr_rsi)==-1)
     {
      Print("CopyBuffer from iRSI failed, no data");
      return(0);
     }

   result=arr_rsi[0]-50.0; // values from the bars that has 0 index

   for(shift=BeginShift+1;shift<limit;shift++)
     {
      rsivalue=arr_rsi[shift]-50;
      if((result>0 && rsivalue<-3) || (result<0 && rsivalue>3))
        {
         RSIAreaShift=shift;
         break;
        }
      result+=rsivalue;
     }
   return(result);
  }

En primer lugar, con la variable result se adjudica el valor del indicador RSI en la barra de más a la derecha menos 50. Después va el ciclo según la matriz arr_rsi, comenzando por elemento con el índice "1" y hasta el elemento con el índice limit-1. En este ciclo se comprueba la condición: "Se ha rebasado o no la línea cero". Si se ha rebasado, entonces el índice de la barra (leemos de derecha a izquierda) se recuerda en la variable RSIAreaShift.

4.5. La función OnTick() del asesor

Hemos terminado de editar la función auxiliar RSIAreaFunc(). Ahora ha llegado el turno de la función comercial principal OnTick(). Añadimos el código siguiente a OnTick(): 

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   static int RSIAreaShift=0;
   int      shift;
   double   RSICurrent,RSILocalMin,RSILocalMax,value;
   double   arr_rsi[1],rsi;
   MqlTick  last_tick;
//---
   if(CopyBuffer(handle,0,0,1,arr_rsi)==-1)
     {
      Print("CopyBuffer from iRSI failed, no data");
      return;
     }
   rsi=arr_rsi[0];
//--- 
   if(!SymbolInfoTick(Symbol(),last_tick))
      Print("SymbolInfoTick() failed, error = ",GetLastError());
//---
  }

Con la ayuda de la función CopyBuffer, que ya conocemos, obtenemos un valor del indicador RSI en la barra de más a la derecha y después asignamos este valor a la variable rsi -. En lo sucesivo, recurriremos más de una vez a esta variable. Acto seguido, obtenemos los precios actuales de este símbolo y guardamos estos precios en la variable last_tick.

El siguiente bloque de código se procesa con la condición de que tengamos una posición abierta para este instrumento:

   if(!SymbolInfoTick(Symbol(),last_tick))
      Print("SymbolInfoTick() failed, error = ",GetLastError());
//--- check the conditions for opening a position
   if(!PositionSelect(Symbol()))
     {
      RSIArea=RSIAreaFunc(RSIAreaShift,0);
      //--- check at the chance to take a long position
      if(RSIArea<-AreaCondition)
        {
         my_trade.Buy(1.0,NULL,last_tick.ask,0.0,0.0,NULL);
         RSIOpen=rsi;
         return;
        }
      //--- check at the chance to take a short position
      if(RSIArea>AreaCondition)
        {
         my_trade.Sell(1.0,NULL,last_tick.bid,0.0,0.0,NULL);
         RSIOpen=rsi;
         return;
        }
      RSIAreaShift=0;
     }
//---
  }
//+------------------------------------------------------------------+
//| Area calculation                                                 |

En el código se comprueban las condiciones para la apertura de posición: si el área calculada en la actualidad (variable RSIArea) es menor/mayor al parámetro de entrada (AreaCondition), entonces se abrirá una posición Buy/Sell, respectivamente.

Después de la variable RSICurrent , se asigna el valor de la variable rsi  (recordemos que en ella se guarda el valor del indicador RSI en la primera barra de todas) y se comprueba la condición de salida de la función OnTick():

  • si la posición ha sido abierta por encima de la línea "50" (RSIOpen>50) y nosotros nos encontramos en este momento por encima de la línea "50" (RSICurrent>50);
  • si la posición ha sido abierta por debajo de la línea "50" (RSIOpen<50) y nosotros nos encontramos en este momento por debajo de la línea "50" (RSICurrent<50);

      RSIAreaShift=0;
     }
   RSICurrent=rsi;
   if(RSIOpen>50 && RSICurrent>50) return;
   if(RSIOpen<50 && RSICurrent<50) return;

   RSILocalMin = RSICurrent;
   RSILocalMax = RSICurrent;

//---
  }
//+------------------------------------------------------------------+
//| Area calculation                                                 |

El siguiente bloque de código encuentra los mínimos/máximos locales y asigna estos valores a las variables RSILocalMinRSILocalMax:

   RSILocalMin = RSICurrent;
   RSILocalMax = RSICurrent;
   
//--- search local minimum/maximum
   if(RSIAreaShift>1)
     {
      double   arr_rsi_1[];
      ArrayResize(arr_rsi_1,RSIAreaShift);
      ArraySetAsSeries(arr_rsi_1,true);
      if(CopyBuffer(handle,0,0,RSIAreaShift,arr_rsi_1)==-1)
        {
         Print("CopyBuffer from iRSI failed, no data");
         return;
        }
      for(shift=1; shift<RSIAreaShift; shift++)
        {
         value=arr_rsi_1[shift];
         if(value<RSILocalMin && RSIArea>0) RSILocalMin=value;
         if(value>RSILocalMax && RSIArea<0) RSILocalMax=value;
        }
     }
//---
  }
//+------------------------------------------------------------------+
//| Area calculation                                                 |

Y, al fin, el último bloque de código:

         if(value>RSILocalMax && RSIArea<0) RSILocalMax=value;
        }
     }

//--- check for rollback
   if(PositionSelect(Symbol()))
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         //--- check, can it is time already be closing?
         if(RSILocalMax>=RSICurrent+4 && RSILocalMax>50)
            my_trade.PositionClose(Symbol(),20);
        }
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         //--- check, can it is time already be closing?
         if(RSILocalMin<=RSICurrent-4 && RSILocalMin<50)
            my_trade.PositionClose(Symbol(),20);
        }
     }
//---
   return;
  }
//+------------------------------------------------------------------+
//| Area calculation                                                 |

Aquí (en el caso de que haya una posición abierta) se comprueba la condición de cierre de la posición según la norma:

El cruce del oscilador RSI de la línea 50 con la subsecuente formación de un máximo/mínimo local y un retroceso con respecto a él con una magnitud del 4% de la escala.
Por ejemplo, después de encontrarse largo tiempo sobre la línea 50, en un cierto momento, tenemos una posición SELL abierta. A continuación, el valor del indicador comienza a disminuir y alcanza, supongamos, la línea 40, después de lo cual, el valor del indicador comienza a aumentar (es decirse forma un mínimo local). La señal de cierre de posición será el momento cuando el valor del indicador alcance la línea 44.

Con esto ya podemos dar por finalizada la creación del asesor RSIAreaExpert_v1 . El archivo "RSIAreaExpert_v1.mq5" se puede descargar al final del artículo.


5. Simulamos el asesor RSIAreaExpert version 1.00 en diferentes periodos y símbolos

La simulación del asesor RSIAreaExpert se realizó inicialmente en el periodo del gráfico H1 [1], pero desde el año 2004 los mercados son más volátiles, y por eso, para comprobar la capacidad de funcionamiento del método de las áreas, se decidió realizar las pruebas en un gran diapasón de periodos: de M10 a H6. También se amplió sustancialmente el diapasón de áreas para la simulación: de 100 a 800. Periodo temporal de la simulación: desde el 2015.01.05 al 2016.01.05.

Bien, aquí tenemos los resultados de la simulación del asesor RSIAreaExpert version 1 para el símbolo AUDCAD:

  RSIAreaExpert version 1 AreaCondition to Profit AUDCAD

Fig. 10.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo AUDCAD. Intervalo de las áreas 100-800. Intervalo de los periodos M10-H6 

En el periodo H2 vemos una buena concentración de resultados. También podemos tomar en cuenta el periodo H3. Miremos ahora la figura de más abajo y valoremos cuántas operaciones se han realizado en un año en el símbolo AUDCAD al realizar la simulación del asesor RSIAreaExpert version 1:

RSIAreaExpert version 1 Trades to Profit AUDCAD

Fig. 11.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo AUDCAD. Intervalo de las áreas 100-800. Intervalo de periodos M10-H6 

En los peridos H2 y H3 la cantidad de operaciones al año oscila dentro de las 50. Esto es poco, y el margen de error es elevado. Podemos llegar a la conclusión de que en el símbolo AUDCAD, la estrategia del método de las áreas funciona mal.

Resultados de la simulación del asesor RSIAreaExpert version 1 para el símbolo AUDUSD

RSIAreaExpert version 1 AreaCondition to Profit AUDUSD 

 Fig. 12.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo AUDUSD. Intervalo de las áreas 100-800. Intervalo de periodos M10-H6 

Si analizamos la rentabilidad de la estrategia en el símbolo AUDUSD, entonces podemos analizar el comercio en los periodos H2 y H3. En estos periodos, el parámetro AreaCondition oscila entre 250 y 400. Para confirmar los argumentos del comercio en los periodos H2 y H3 hay que fijarse en la cantidad de transacciones en un año en estos periodos:

RSIAreaExpert version 1 Trades to Profit AUDUSD 

 Fig. 13.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo AUDUSD. Intervalo de las áreas 100-800. Intervalo de periodos M10-H6 

Como podemos ver, la cantidad es raquítica. Significa que en AUDUSD no se recomienda comerciar con el método de las áreas.

Resultados de la simulación del asesor RSIAreaExpert version 1 para el símbolo b0>EURUSD:

RSIAreaExpert version 1 AreaCondition to Profit EURUSD

 Fig. 14. Resultados de la simulación del asesor RSIAreaExpert. Intervalo de las áreas 100-800. Intervalo de los periodos M10-H6  

En la figura 4 podemos ver que para el periodo M10 se observa una buena concentración de resultados con beneficio para el diapasón de áreas de 400 a 550, para el periodo M12, de 300 a 400 y para el periodo M15, de 300 a 400. No vamos a analizar periodos más altos, puesto que la cnatidad de operaciones al año es demasiado pequeña (ver fig. 5).

En la figura 5 se muestra el gráfico de dependencia entre la cantidad de operaciones y el beneficio para el símbolo EURUSD:

RSIAreaExpert version 1 Trades to Profit EURUSD

Fig. 15. Resultados de la simulación del asesor RSIAreaExpert. Intervalo de las áreas 100-800. Intervalo de los periodos M10-H6 

Aquí se ve bien que en los periodos altos (de H1 a H6) la cantidad de operaciones es diminuta, lo que pone en duda la justificación del uso del método de las áreas en estos periodos. Pero en los periodos M10, M12 y M15 la cantidad de operaciones es suficiente para confirmar la rentabilidad del método de las áreas en estos marcos temporales. Definitivamente, el símbolo EURUSD es adecuado para comerciar con el método de las áreas.

Resultados de la simulación del asesor RSIAreaExpert version 1 para el símbolo GBPUSD:

RSIAreaExpert version 1 AreaCondition to Profit GBPUSD 

 Fig. 16.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo GBPUSD. Intervalo de las áreas 100-800. Intervalo de periodos M10-H6 

En el símbolo GBPUSD hay una buena concentración de beneficio positivo para el periodo M20. La dispersión del parámetro AreaCondition es de 300 a 500.

RSIAreaExpert version 1 Trades to Profit GBPUSD 

Fig. 17.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo GBPUSD. Intervalo de las áreas 100-800. Intervalo de periodos M10-H6  

Para el símbolo GBPUSD y en el periodo M20, la cantidad de operaciones al año oscila entre 140 y 250. Ciertamente, no es un dato fantástico, pero, sin embargo, se puede tener en cuenta. En otras palabras, comerciar con el símbolo GBPUSD con el método de las áreas es algo que ya depende de cada uno. 

Resultados de la simulación del asesor RSIAreaExpert version 1 para el símbolo USDCAD:

 

Fig. 18.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo USDCAD. Intervalo de las áreas 100-800. Intervalo de periodos M10-H6  

En el símbolo USDCAD solo echaría un vistazo al periodo M30, dado que solo en este se observa una buena concentración de beneficio positivo. Además, el parámetro AreaCondition cambia en un diapasón de 280 a 550.

RSIAreaExpert version 1 Trades to Profit USDCAD 

 Fig. 19.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo USDCAD. Intervalo de las áreas 100-800. Intervalo de periodos M10-H6  

Aquí la cantidad de operaciones en un año en esta pareja de divisas con el marco temporal M30 oscila entre 90 y 200. No son muchas operaciones, por eso el método de las áreas para  el símbolo USDCAD no es algo que yo recomendaría.

Resultados de la simulación del asesor RSIAreaExpert version 1 para el símbolo USDJPY:

RSIAreaExpert version 1 AreaCondition to Profit USDJPY 

Fig. 20.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo USDJPY. Intervalo de las áreas 100-800. Intervalo de periodos M10-H6  

En el símbolo USDJPY destacan dos periodos: M10 y M30. El parámetro AreaCondition para el periodo M10 se encuentra entre 320 y 650, para el periodo M30, entre 550 y 600.

RSIAreaExpert version 1 Trades to Profit USDJPY 

Fig. 21.  Resultados de la simulación del asesor RSIAreaExpert version 1. Símbolo USDJPY. Intervalo de las áreas 100-800. Intervalo de periodos M10-H6  

Para el símbolo USDJPY, la cantidad de operaciones en un año con el método de las áreas para el periodo M10 está entre 150 y 200, y para el símbolo M30, entre 50 y 150. De esta forma, podemos ver que las recomendaciones sobre el comercio son demasiado difusas.


Conclusión

Así que aún es pronto para tachar de la lista el método de las áreas. Es cierto que con las condiciones actuales en los mercados, el sistema ha comenzado a mostrar pérdidas en el periodo H1, aunque antes [1] el beneficio principal se mostraba precisamente en él. En el mercado actual, el comercio más rentable y con mejores resultados ha tenido lugar con el método de las áreas en el símbolo EURUSD y en los periodos M10, M12 y M15. Precisamente en esta pareja de divisas y en estos marcos temporales la simulación ha mostrado una cantidad suficiente de operaciones durante el año.

 

Lista de literatura utilizada

  1. Morozov I. V., Fatkhullin R.R. FOREX: de lo sencillo a lo complejo. Nuevas posibilidades con el terminal de cliente "MetaTrader". - М: "Teletrade" SL, 2004. - p.448.
Cómo instalar correctamente los indicadores y asesores desde los archivos al final del artículo: los archivos "Indicators.zip" y "Experts.zip" deben ser descomprimidos en el <catálogo de datos>\MQL5\

Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/2249

Archivos adjuntos |
Indicators.zip (3.91 KB)
Experts.zip (5.37 KB)
Fundamentos de la codificación de un asesor experto de cobertura Fundamentos de la codificación de un asesor experto de cobertura
En este artículo se muestra un asesor experto de cobertura. El autor elegirá su propio par de cobertura que es EURJPY y GBPJPY. Siempre se mueve de la misma forma, más fácilmente para establecer el tipo de orden de cobertura.
¿Puede predecirse el mercado Forex? ¿Cómo crear una estrategia de trading propia? ¿Puede predecirse el mercado Forex? ¿Cómo crear una estrategia de trading propia?
Todo el que empieza a trabajar en Forex intenta responder a estas preguntas. Pero no todos encuentran la respuesta, incluso después de muchos años de duro trabajo y búsqueda. Personalmente, he respondido a esta pregunta y muchas otras de este artículo. Como resultado de estas respuestas se ha determinado una forma eficiente de crear una estrategia de trading.
Enviando señales de trading a través de feeds RSS Enviando señales de trading a través de feeds RSS
Esta es mi idea sobre cómo enviar nuestras señales de trading como FEEDS RSS, una popular forma de comunicarnos con los miembros de nuestra comunidad ahora mismo.
Elección automática de una empresa de corretaje para un funcionamiento eficiente de los asesores expertos Elección automática de una empresa de corretaje para un funcionamiento eficiente de los asesores expertos
No es un secreto que para lograr un funcionamiento eficiente de los asesores expertos necesitamos encontrar una empresa de corretaje adecuada. Este artículo describe un sistema para hacer esta búsqueda. Se familiarizará con el proceso de creación de un programa con dll para trabajar con distintos terminales.