Mira cómo descargar robots gratis
¡Búscanos en Facebook!
Pon "Me gusta" y sigue las noticias
¿Es interesante este script?
Deje un enlace a él, ¡qué los demás también lo valoren!
¿Le ha gustado el script?
Evalúe su trabajo en el terminal MetaTrader 5
Asesores Expertos

Media Móvil (Moving Average) - Asesor Experto para MetaTrader 5

Visualizaciones:
4747
Ranking:
(53)
Publicado:
2014.01.14 12:54
Actualizado:
2018.06.04 17:55
¿Necesita un robot o indicador basado en este código? Solicítelo en la bolsa freelance Pasar a la bolsa

El EA Media Móvil está incluido en el paquete estándar del terminal cliente MetaTrader 5 y es un ejemplo de EA que utiliza el indicador Media Móvil .

El archivo EA Moving Average.mq5 se encuentra en la carpeta "terminal_data_folder\MQL5\Experts\Examples\Moving Average\". Este EA es un ejemplo del uso de indicadores técnicos, funciones histórico de trades y clases de tradings de la librería estándar. Además, el EA incluye un sistema de administración de dinero que se basa en los resultados de trades.

Consideremos la estructura del EA y cómo trabaja.

1. Propiedades del EA

//+------------------------------------------------------------------+
//|                                              Moving Averages.mq5 |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2013, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00

Las 5 primeras filas contienen un comentario, las tres líneas siguientes establecen las propiedades del programa MQL5 (derechos de autor, link, versión) usando las directivas del preprocesador #property.

Cuando se ejecuta el asesor experto se muestran en la pestaña "Común":

Propiedades del EA de Media Móvil

Figura 1. Parámetros comunes del EA de Media Móvil

1.2. Incluir archivos

A continuación, la directiva #include indica al compilador que incluya el archivo "Trade.mqh".

Este archivo es parte de La librería estándar, que contiene la clase CTrade para facilitar el acceso a las funciones de trading.

#include <Trade\Trade.mqh>

El nombre del archivo incluido se muestra en los soportes "<>;", así se establece la ruta de acceso relativa al directorio: "terminal_data_folder\Include\".

1.3 Entradas

Luego va el tipo, nombre, valores predeterminados y un comentario. Su función se muestra en la figura 2.

input double MaximumRisk        = 0.02;    // Riesgo máximo en porcentaje
input double DecreaseFactor     = 3;       // factor decrease
input int    MovingPeriod       = 12;      // Periodo del MA
input int    MovingShift        = 6;       // Cambio del MA

Los parámetros MaximumRisk y DecreaseFactor se utilizarán para administrar su dinero, MovingPeriod y MovingShift establecen el período y el cambio del indicador técnico Media Móvil que se utilizará o comprobará las condiciones de trade.

El texto en el comentario en la línea de parámetro de entrada, junto con los valores por defecto, se muestran en la pestaña "Opciones" en lugar del nombre del parámetro de entrada:

Parámetros de entrada del EA de Media Móvi

Fig. 2. Parámetros de entrada del EA de Media Móvil

1.4. Variables globales

Entonces se declara la variable global ExtHandle. Se utilizará para almacenar el manejo del indicador de la Media Móvil .

//---
int   ExtHandle=0;

Es seguido por 6 funciones. El propósito de cada una de ellas se describe en el comentario antes de cuerpo de la función:

  1. TradeSizeOptimized() - Calcula el tamaño del lote óptimo;
  2. CheckForOpen() - Verifica de las condiciones de la posición abierta;
  3. CheckForClose() - Busca las condiciones de la posición de cierre;
  4. OnInit() - función de inicio del experto;
  5. OnTick() - Función de tick frl experto;
  6. OnDeinit() - Función de deinicialización el experto;

Las tres últimas funciones son funciones de gestión de eventos; las tres primeras funciones de servicio se llaman en su código.


2. Funciones de Gestión de Eventos

2.1. La función de inicio OnInit()

La función OnInit() se llama una vez durante el primer inicio del EA. Generalmente en el controlador de eventos OnInit() el EA se prepara para la operación: se comprueban los parámetros de entrada, indicadores y parámetros se inicializan, etc.. En el caso de errores críticos, cuando más trabajo tiene sentido, la función se sale con un código de retorno INIT_FAILED.

//+------------------------------------------------------------------+
//| Función de inicio del experto                                    |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//---
   ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
   if(ExtHandle==INVALID_HANDLE)
     {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }

Puesto que el comercio del EA se basa en el indicador de Media Móvil, llamando al iMA() el indicador Media Móvil se crea y su manejo se guarda en la variable ExtHandle global.

En el caso de un error, OnInit() se sale con un código de retorno INIT_FAILED - es una forma correcta de completar la operación EA/indicador en el caso de una inicialización fracasada.

2.2. Función OnTick()

La función OnTick() se llama cada vez que se recibe una nueva cotización para el símbolo de la gráfica, en la cual funciona el EA.

//+------------------------------------------------------------------+
//| Función tick del Expert                                          |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   if(PositionSelect(_Symbol))
      CheckForClose();
   else
      CheckForOpen();
//---
  }

La función PositionSelect() se utiliza para definir si hay una posición abierta para el símbolo actual.

Si hay posiciones abiertas, se llama la función CheckForClose(), que analiza el estado actual del mercado y cierra la posición abierta, de lo contrario se llama a CheckForOpen(), que verifica las condiciones de entrada en el mercado y abre una nueva posición si se presentan tales condiciones.

2.3. Función de deinicialización OnDeInit()

OnDeInit() se llama cuando un EA se elimina de la tabla. Si un programa coloca objetos gráficos durante la operación, pueden eliminarse de la gráfica.

//+------------------------------------------------------------------+
//| Función de deinitialización                                      |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+

En este caso no se realizará ninguna acción durante deinicialización del Asesor Experto.

3. Funciones de Servicio

3.1. Función TradeSizeOptimized()

Esta función calcula y devuelve el valor del tamaño del lote óptimo para la posición de apertura con el nivel especificado de riesgo y resultados de trading.

//+------------------------------------------------------------------+
//| Cálculo del tamaño óptimo del lote                               |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
  {
   double price=0.0;
   double margin=0.0;
//--- Cálculo del tamaño óptimo del lote
   if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
      return(0.0);
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
      return(0.0);
   if(margin<=0.0)
      return(0.0);

   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_FREEMARGIN)*MaximumRisk/margin,2);
//--- calcula la longitud de la serie de operaciones perdedoras consecutivas
   if(DecreaseFactor>0)
     {
      //--- solicitar todo el hitórico de trading
      HistorySelect(0,TimeCurrent());
      //--
      int    orders=HistoryDealsTotal();  // número total de ofertas
      int    losses=0;                    // número de ofertas con pérdidas en la serie

      for(int i=orders-1;i>=0;i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         if(ticket==0)
           {
            Print("HistoryDealGetTicket failed, no trade history");
            break;
           }
         //--- checking the deal symbol
         if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
            continue;
         //--- checking the profit
         double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
         if(profit>0.0)
            break;
         if(profit<0.0)
            losses++;
        }
      //---
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- normalizing and checking the allowed values of the trade volume
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot=stepvol*NormalizeDouble(lot/stepvol,0);

   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(lot<minvol)
      lot=minvol;

   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(lot>maxvol)
      lot=maxvol;
//--- devuelve el valor del volumen de tradingo
   return(lot);
  }

La función SymbolInfoDouble() se utiliza para comprobar la disponibilidad de precios para el símbolo actual, luego se utiliza la función OrderCalcMargin() para solicitar el margen requerido para realizar una orden (en este caso una orden de compra). El tamaño del lote inicial es determinado por el valor del margen para colocar la orden, el margen libre de la cuenta (AccountInfoDouble(ACCOUNT_FREEMARGIN)) y el valor máximo permitido de riesgo especificado en el parámetro de entrada MaximumRisk.

Si el valor del parámetro de entrada DecreaseFactor es positivo, se analizan los acuerdos en el histórico y el tamaño del lote se ajusta teniendo en cuenta la información sobre la serie máxima de trades perdidos: el tamaño del lote inicial se multiplica por el tamaño (1-pérdidas/DecreaseFactor).

Entonces el volumen de comercio es "redondeado" al valor que es múltiplo del paso mínimo permisible del volumen (stepvol) para el símbolo actual. También se pide el mínimo (minvol) y los valores máximos posibles (maxvol) del volumen de trade, y si el valor del lote sale de los límites permitidos, se ajusta. Como resultado, la función devuelve el valor calculado del volumen de trading.

3.2. Función CheckForOpen()

CheckForOpen() se utiliza para comprobar las condiciones de las posiciones abiertas y las abre cuando se produzcan las condiciones comerciales (en este caso cuando el precio cruza la media móvil).

//+------------------------------------------------------------------+
//| Ajuste de las condiciones de las posiciones abiertas             |
//+------------------------------------------------------------------+
void CheckForOpen(void)
  {
   MqlRates rt[2];
//--- copia los valores de los precios
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
//--- Trade sólo en el primer tick o en la nueva barra
   if(rt[1].tick_volume>1)
      return;
//--- Obtener el valor actual del indicador de media móvil 
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer del iMA fallido, sin datos");
      return;
     }
//--- ajuste de la señal
   ENUM_ORDER_TYPE signal=WRONG_VALUE;

   if(rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=ORDER_TYPE_SELL;    // condiciones de venta
   else
     {
      if(rt[0].open<ma[0] && rt[0].close>ma[0])
         signal=ORDER_TYPE_BUY;  // condiciones de compra
     }
//--- ajustes adicionales
   if(signal!=WRONG_VALUE)
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         if(Bars(_Symbol,_Period)>100)
           {
            CTrade trade;
            trade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
                               SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                               0,0);
           }
//---
  }

Cuando se opera con el movimiento, tienes que comprobar si precio cruza la media móvil. Utilizando la función CopyRates() , dos valores de los precios actuales se copian en la matriz de estructuras rt [], rt [1] corresponde a la barra actual, rt [0] - barra completada.

Se inicia una nueva barra controlando el volumen de la señal de la barra actual si es igual a 1, entonces ha comenzado una nueva barra. Cabe señalar que este método de detección de una nueva barra puede fallar en algunos casos (cuando las cotizaciones vienen en paquetes), así que el hecho del inicio de una nueva formación de barra debe ser realizado guardando y comparando el tiempo de la cotización actual (ver IsNewBar).

El valor actual del indicador promedio móvil se solicita mediante la función CopyBuffer() y se guarda en la matriz ma[] que contiene un solo valor. A continuación el programa comprueba si el precio ha cruzado la media móvil y hace comprobaciones adicionales (es posible si el trading utiliza el EA y la presencia de barras en el histórico). Si tiene éxito, se abre una posición adecuada para el símbolo llamando al método PositionOpen() del objeto de trade (una instancia de CTrade).

Se establece el precio de apertura de la posición mediante la función SymbolInfoDouble() que devuelve el precio de oferta o pregunta dependiendo del valor de la variable de la señal. El volumen de la posición se determina llamando al TradeSizeOptimized() descrito anteriormente.

3.3. Función CheckForClose()

CheckForClose() comprueba las condiciones de la posición de cierre y cierra si se presentan condiciones para cerrarla.

//+------------------------------------------------------------------+
//| ajuste de las condiciones de las posiciones de cierre            |
//+------------------------------------------------------------------+
void CheckForClose(void)
  {
   MqlRates rt[2];
//--- Copia los valores de los precios
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
//--- Trade sólo en el primer tick o en la nueva barra
   if(rt[1].tick_volume>1)
      return;
//--- obtener el valor actual del indicador Media Móvil
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer del iMA fallido, sin datos");
      return;
     }
//--- obtener el tipo de la posición seleccionada anteriormente usando PositionSelect()
   bool signal=false;
   long type=PositionGetInteger(POSITION_TYPE);

   if(type==(long)POSITION_TYPE_BUY   && rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=true;
   if(type==(long)POSITION_TYPE_SELL  && rt[0].open<ma[0] && rt[0].close>ma[0])
      signal=true;
//--- ajustes adicionales
   if(signal)
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         if(Bars(_Symbol,_Period)>100)
           {
            CTrade trade;
            trade.PositionClose(_Symbol,3);
           }
//---
  }

El algoritmo de la función CheckForClose() es similar al algoritmo de CheckForOpen(). Dependiendo de la dirección de las actuales posiciones abiertas, se comprueban otra vez las condiciones de cierre (precio cruzando el MA hacia abajo para comprar o vender hacia arriba). Una posición abierta se cierra mediante una llamada al método PositionClose() del objeto de trade (instancia de CTrade).

4. Backtesting

Los mejores valores de los parámetros se pueden encontrar con el Probador de Estrategias del terminal MetaTrader 5.

Por ejemplo, al optimizar el parámetro MovingPeriod en el intervalo 2012.01.01-2013.08.01, los mejores resultados se obtienen con MovingPeriod = 45:

Resultados de backtesting del Asesor Experto de Media Móvil

Resultados de backtesting del Asesor Experto de Media Móvil

Conclusiones:

The Moving Average Expert Advisor included in the standard pack of the MetaTrader 5 terminal is an example of use of technical indicators, trading history functions and trade classes of the Standard Library. Además, el EA incluye un sistema de administración de dinero que se basa en los resultados de trades.

Traducción del ruso realizada por MetaQuotes Ltd
Artículo original: https://www.mql5.com/ru/code/1921

Módulo de señales de trading basado en el indicador Stalin Módulo de señales de trading basado en el indicador Stalin

Módulo de señales de trading para el asistente MQL5. La flecha de color del indicador Stalin sirve como señal de entrada en mercado.

Trading signals module based on Sidus indicator Trading signals module based on Sidus indicator

Módulo de señales de trading para el Asistente MQL5. La flecha de color del indicador Sidus sirve como una señal de entrada del mercado.

iSimpleClock_v2 iSimpleClock_v2

Reloj sencillo que se muestra en el objeto gráfico "etiqueta" (OBJ_LABEL).

CCalendarInputBox CCalendarInputBox

El nuevo control CCalendarInputBox de la biblioteca IncGUI se ha diseñado para introducir fechas y horas.