En este artículo vamos a mostrar como crear un indicador modificado para Metatrader 4 usando la media móvil exponencial (EMA) como ejemplo. Vamos a usar el MetaEditor de MT4 y mostrar paso a paso cómo se codifica un indicador personalizado desde el inicio.

Metatrader 4, y su hermana Metatrader 5, es una plataforma de trading muy versátil que cuenta con múltiples herramientas de trading y análisis. También tiene su propio lenguaje de programación, denominado MQL4, que permite crear scripts, indicadores personalizados y sistemas automatizados de trading basados en todo tipo de conceptos y enfoques del análisis técnico.

Gracias a esta capacidad, el trader puede crear sus propios indicadores basados en sus ideas del mercado y diseñar sistemas de trading simples y complejos que no podrían implementar con los indicadores más tradicionales. De hecho, existen muchos sistemas de trading, algunos bastante novedosos y rentables, que están diseñados con base en indicadores personalizados para MT4 y que solo pueden ser utilizados en esta plataforma de trading.

Pueden acceder a una lista completa de sistemas de trading basados en indicadores personalizados para Metatrader 4 en la siguiente sección: Estrategias de Trading Para MT4

Sin más dilaciones, vamos a comenzar a explicar el proceso básico para crear indicadores personalizados usando la EMA como ejemplo.

Pasos para crear un indicador personalizado de medias móviles exponenciales (EMA) en Metatrader 4

Aclaración: Para no extendernos demasiado en este tutorial no vamos a explicar en detalle las distintas variables predefinidas, funciones y operadores que vamos a usar en el código del indicador. Pueden encontrar información detallada sobre el lenguaje MQL4 en los siguientes sitios oficiales de MetaQuotes:

Para comenzar, debemos ingresar a nuestra plataforma Metatrader 4 en donde podemos acceder al MetaEditor en donde se realiza la programación y compilación de los indicadores personalizados y otros programas desarrollados en MQL4.

Una vez que accedemos a Metatrader 4, podemos activar el MetaEditor pulsando la tecla F4 en su computadora o haciendo clic en el siguiente botón en la interfaz de la plataforma:

Creación de indicador personalizado en Metatrader 4

Cuando se activa el MetaEditor aparece la siguiente interfaz:

 MetaEditor de Metatrader 4

Una vez que estamos en el MetaEditor, para crear nuestro indicador personalizado hacemos clic en el botón Nuevo ubicado debajo de Archivo, cerca de la esquina superior izquierda (está marcado con rojo en la imagen anterior).

Nos aparece el Asistente Para MQL donde indicamos que tipo de programa queremos crear. Podemos escoger entre Asesor Experto, Indicador Personalizado, Script, Librería, Base de Datos y Script de Python, entre otros. Aquí, lógicamente seleccionamos Indicador Personalizado como muestra la siguiente imagen:

Asistente de Metatrader 4

Una vez que seleccionamos el tipo de programa que queremos crear, hacemos clic en Siguiente y aparece la siguiente pantalla donde debemos indicar el nombre del indicador, el autor y el enlace a alguna página que queremos enlazar:

Al indicador lo vamos a llamar Media_EMA, dado que es un indicador personalizado cuyo objetivo es mostrar una media móvil exponencial (EMA) sobre la acción del precio, en cualquier gráfico de precios.

Una vez que completamos los datos del indicador hacemos clic en el botón Siguiente que nos lleva a otra pantalla donde debemos seleccionar los manejadores de eventos adicionales para el indicador. Por lo general, el único que se deja marcado es OnCalculate y los otros se dejan en blanco.

La función OnCalculate () se llama solo en indicadores personalizados cuando es necesario calcular los valores del indicador mediante el evento Calculate. Esto suele ocurrir cuando se recibe un nuevo tick para el símbolo, para el cual se calcula el indicador. No es necesario adjuntar este indicador a ningún gráfico de precios de este símbolo.

MQL4 tiene otras funciones como OnStart() u OnTick() que solo se usan en Scripts y EA. También está la función OnInit() que se ejecuta cuando el indicador es activado o inicializado y la función OnDeInit() que se ejecuta cuando el indicador es desactivado o desinicializado.

Más información sobre las funciones de eventos en MQL4 en el siguiente artículo: https://docs.mql4.com/basis/function/events

Si todo está bien con los manejadores de eventos del indicador hacemos clic en el botón Siguiente para continuar. Nos aparece la siguiente ventana:

Parámetros de indicadores personalizados MQL4

Esta es la ventana donde se determinan los parámetros de visualización del indicador. Aquí podemos establecer si el indicador será trazado sobre la acción del precio directamente en el gráfico o en una ventana aparte debajo del gráfico, como en el caso de los osciladores. Como el indicador que vamos a desarrollar es una media móvil, dejamos la casilla Indicador en la ventana separada sin marcar.

Si seleccionamos la opción de Indicador en la ventana separada, podemos establecer un valor máximo y un valor mínimo para el indicador, como en el caso de ciertos osciladores como el RSI (0 a 100). Este paso no es indispensable.

Abajo indicamos la forma de visualización que tendrá el indicador y podemos asignarle una etiqueta para su identificación y un color. Podemos escoger entre una Línea, Histograma, Flecha, Sección y Zigzag.

Lógicamente, en este caso seleccionamos Línea ya que el indicador personalizado es una media móvil.

Si así lo deseamos, podemos dejar esta sección en blanco y agregar esta información durante la codificación del indicador, como veremos más adelante.

Una vez que terminamos, hacemos clic en el botón Finalizar. Con esto aparece el Editor de programas, la parte más importante de MetaEditor, donde se realiza la codificación del indicador personalizado.

Sección de la Cabecera del indicador personalizado

Primero tenemos la cabecera (Header) en donde se muestra la información general del indicador (Nombre, Autor y un enlace seleccionado por el autor), se indican sus propiedades básicas, incluyendo las referentes a su trazado en la plataforma, y se definen el número de buffers, arrays y variables principales.

En el caso del indicador Media_EMA tenemos el siguiente código en la cabecera que describiremos brevemente:

#property copyright «Raul Canessa»: Sirve para indicar el nombre del autor o propietario del indicador

#property link  «https://www.tecnicasdetrading.com/«: Permite enlazar a cualquier sitio web que desee el autor.

#property version  «1.02»: Indica la versión del indicador.

#property strict: Directiva del compilador para el modo de compilación estricto

#property description «Media móvil exponencial (EMA) creada con fines ilustrativos. «: Breve descripción textual de un indicador personalizado de MQL4. Pueden estar presentes varias descripciones, cada una de ellas describe una línea del texto.

Los siguientes son parámetros específicos cuyo objetivo es la inicialización y definición del trazado del indicador.

#property indicator_chart_window: Este parámetro indica que el indicador será trazado superpuesto a la misma acción del precio en el gráfico y no en una ventana aparte.

#property indicator_buffers 1: Con esto señalamos que el indicador usará solo un buffer para el cálculo del indicador (la EMA está compuesta por una sola línea).Un búfer es un área de memoria que contiene valores numéricos de un array (variable de matriz) de un indicador.

#property indicator_color1 Red: Permite determinar el color del indicador. En este caso la línea de la EMA será de color rojo.

A continuación se definen las principales variables simples y variables de matriz usadas en el cálculo del indicador.

extern int Periodo_EMA=10: Aquí definimos la variable Periodo_EMA que usamos para indicar el número de periodos retrospectivos usados en el cálculo de la EMA (valor por defecto 10 periodos). Con extern le indicamos a la terminal que es una variable externa cuyo valor puede ser modificada por el usuario al aplicar el indicador o en cualquier momento después de su activación. Con int indicamos que se trata de una variable entera (no acepta números con decimales).

input ENUM_APPLIED_PRICE  Precio_Aplicado=0; Aquí definimos una variable entera usada para indicar el tipo de precio usado en el cálculo de la EMA (valor por defecto 0). Aquí el trader puede escoger entre el precio de cierre (0), precio de apertura(1), precio máximo (2), precio mínimo (3), precio mediano (4), precio típico (5) y precio ponderado (6).

double K: Aquí definimos la variable K usada para el cálculo del Factor de Suavizado de la EMA (veremos en qué consiste más adelante cuando expliquemos cómo se calcula la media móvil exponencial). Con double indicamos que se trata de una variable real (acepta decimales), lo que será necesario más adelante cuando calculemos el factor de suavizado.

double EMA[]: Es la declaración de la variable de matriz usada para obtener los valores de la EMA que se usarán en el trazado del indicador.

double Tipo_Precio[]: Es la declaración de la variable de matriz empleada para determinar el tipo de precio usado en el cálculo del indicador.

Aquí termina el código usado en la cabecera del indicador. En esta sección le damos al indicador sus características esenciales y definimos las variables principales y los arrays usados en el cálculo del indicador personalizado. Sin embargo, aún no realizamos ningún cálculo, solo sentamos las bases de la EMA.

Ahora vamos a pasar a la función OnInit(), donde se coloca el código que se ejecutará una sola vez al iniciar el indicador.

Función OnInit()

Una vez que acabamos de colocar el código necesario en la Cabecera, nos enfocamos en la función OnInit().

Aquí se coloca el código que se ejecutará una sola vez cada vez que el indicador es activado y adjuntado a un gráfico de precios. Pero lo más importante es que es en esta función donde se agrega el mapa de buffers usados en los cálculos requeridos para el trazado del indicador.

Específicamente, es donde se define el número de buffers que se usarán y se asignan estos a las variables de matriz definidas en la cabecera. Cada variable de matriz debe tener un buffer asignado, que actuará como una memoria en donde se guardarán los valores asignados a la variable.

El código agregado en OnInit() para el indicador Media_EMA es el siguiente:

IndicatorBuffers(2): Con este código le indicamos a la terminal que el indicador usará dos buffers para los cálculos.

SetIndexBuffer(0,EMA): Con SetIndexBuffer indicamos que estamos asignando el primer buffer a la variable de matriz EMA[].

SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2): Sirve para definir el estilo de línea del indicador

SetIndexBuffer(1,Tipo_Precio): Este código sirve para la asignación del segundo buffer a la variable de matriz Tipo_Precio.

SetIndexStyle(1,DRAW_NONE,EMPTY,clrNONE):  En este caso el código empleado indica que para este buffer no se trazará ninguna línea, es decir que no será visible ya que solo se usará con propósitos de cálculo.

La siguiente serie de códigos, que comienza en //Etiqueta de Técnicas de Trading, sirve para mostrar una etiqueta en una esquina del gráfico de precios con el nombre del indicador y el nombre de este sitio.

ObjectCreate(«Label_Tecnicas», OBJ_LABEL, 0, 0, 0): Creación de etiqueta de TecnicadeTrading

ObjectSet(«Label_Tecnicas», OBJPROP_CORNER, 0): Define la esquina de referencia

ObjectSet(«Label_Tecnicas», OBJPROP_XDISTANCE, 20): Define la  coordenada X donde se colocará la etiqueta.

ObjectSet(«Label_Tecnicas», OBJPROP_YDISTANCE, 25): Define la  coordenada Y donde

ObjectSetText(«Label_Tecnicas»,«EMA – TecnicasDeTrading.com»,16,«Arial»,Blue): Define el texto de la etiqueta junto con el tamaño, tipo y color de las  letras.

En estas líneas de código que se agregan debajo del código anterior, se le indica a la plataforma que se elimine la etiqueta anterior una vez que se desactive el indicador.

A continuación vamos a explicar el código que calcula el valor de la media móvil exponencial en cada tick que recibe la plataforma. Sin embargo, antes vamos a indicar brevemente cómo se calcula esta media móvil para tener una mayor comprensión del código que se presentará más adelante.

Cálculo de la media móvil exponencial (EMA)

La EMA es un tipo de media móvil ponderada (WMA) que da más ponderación o importancia a los datos de precios recientes. Al igual que la media móvil simple (SMA), la EMA se usa para ver las tendencias de precios a lo largo del tiempo y detectar posibles cambios en la dirección del mercado, filtrando el ruido y los cambios de dirección de corta duración.

La fórmula para calcular la EMA consiste básicamente en utilizar un multiplicador y comenzar con la SMA. Los pasos son los siguientes:

  • Calcular la SMA que servirá como valor inicial de la EMA
  • Calcular el multiplicador para ponderar la EMA
  • Calcular la EMA actual

El cálculo de la SMA es lo mismo que calcular un promedio o media. Es decir, la SMA para cualquier número dado de períodos de tiempo es simplemente la suma de los precios para cada uno de esos períodos de tiempo, dividida por la cantidad de períodos de tiempo. Entonces, por ejemplo, una SMA de 10 días es solo la suma de los precios de cierre de los últimos 10 días, dividida por 10.

La fórmula matemática es la siguiente:

Media Móvil Simple (SMA)=(Suma de Precios)/N

Donde:

  • Suma de Precios:  Suma de los precios del instrumento en cada periodo usado en el cálculo de la SMA.
  • N: Número total de periodos usado en el cálculo de la SMA.

La fórmula para calcular el multiplicador de ponderación, también conocido como constante de suavizado, es la siguiente:

Multiplicador de Ponderación (K) =2/(1+N)

Si N=10, entonces el valor del multiplicador de ponderación es el siguiente:

= 2 ÷ (período de tiempo seleccionado + 1)

= 2 ÷ (10 + 1)

= 0,1818

= 18,18%

La fórmula final para el cálculo de la EMA es la siguiente:

EMA (t) = Precio (t) × K + EMA (t-1) × (1 − K)

donde:

  • EMA(t) = EMA del periodo actual
  • EMA (t-1) = EMA del periodo anterior
  • t = periodo actual
  • t-1 = ayer
  • N = número de periodos en la EMA
  • K= multiplicador de ponderación = 2/(N + 1)

Con base en esta fórmula, podemos ver que la ponderación dada al precio más reciente es mayor para una EMA de período más corto que para una EMA de período más largo.

Ahora vamos a mostrar el código más importante de este indicador personalizado, el que sirve para el cálculo de la EMA.

Función OnCalculate()

Una vez que terminamos de colocar el indicador en OnInit(), nos vamos a la sección OnCalculate() en donde se coloca el código que servirá para el cálculo del indicador propiamente dicho. Este código se ejecutará cada vez que la plataforma y un programa reciban un tick del servidor del broker, es decir con cada precio nuevo.

Cálculo del indicador personalizado

El código de cálculo realmente comienza donde sale el encabezado //Variables de cálculo.

Antes que nada queremos aclarar lo siguiente. El código que utilizamos en este ejemplo es solo una forma entre muchas en que se puede calcular la EMA u otro indicador similar usando el lenguaje MQL4. La creación de cualquier programa informático depende en gran medida del programador y su experiencia. Un programador experto en MQL4 probablemente podría crear el mismo indicador de forma más rápida y simple.

Por lo tanto, este indicador personalizado no debe tomarse como una forma única para programar la media móvil exponencial en MT4. Solamente es un ejemplo que muestra cómo se puede crear un indicador personalizado en Metatrader 4 desde cero.

Ahora, volviendo al código, en //Variables de cálculo tenemos la declaración de las distintas variables que vamos a usar para calcular cada valor de la EMA:

int i: Declaración de variable i para conteo de barras usadas en el cálculo de la EMA. El código int le indica a la plataforma que la variable i es de tipo entera (sin decimales).

int j;  Declaración de variable j para el primer valor de la EMA

int n=0: Declaración de variable de cálculo n para los valores subsecuentes de la EMA

int r:  Declaración de variable de cálculo r para seleccionar los tipos de precios usados

double p=Periodo_EMA: Declaración de variable p usada para conversión de variable entera Periodo_EMA a variable real para cálculo de K. El código double le indica a la plataforma que la variable p es de tipo real (con decimales).

double Suma: Declaración de variable real Suma usada para determinar primer valor de EMA (valor de media móvil simple que se usa como valor inicial de EMA).

int Cant_Bars: Declaración de variable Cant_Bars usada para el cálculo de la cantidad de barras contadas por el indicador en cada tick.

Las dos líneas de código que se colocan debajo de //Conteo de barras para el cálculo del indicador sirven para determinar la cantidad de barras usadas en el cálculo de la EMA en cada tick que recibe la plataforma.

Cant_Bars=IndicatorCounted(): Esta línea de código sirve para el conteo de barras por parte del indicador en cada tick. La función IndicatorCounted() devuelve la cantidad de barras que no se modificaron después de que se lanzó el indicador por última vez o después de cada tick recibido.

i=Bars-Cant_Bars-1: Esta línea sirve para establecer la cantidad de barras usadas en el cálculo del indicador en cada tick. La función Bars devuelve el número de barras contadas en el historial para un símbolo y un período especificados.

Ahora que terminamos con la declaración de las variables de cálculo y el conteo de barras, nos vamos a enfocar en el código que realiza el cálculo de los valores de la EMA, comenzando con el código para el cálculo de K.

Calculo de EMA MQL4

A partir del encabezado //Cálculo de la EMA, tenemos dos secciones de código, una donde se calcula el valor de K, y otra donde se determina el tipo de precio usado en el cálculo de la EMA.

K=2/(p+1): Código para el cálculo de K usando la variable p (variable en donde se convirtió el valor de la variable Periodo_EMA en número real).

//Precio usado para el cálculo de la EMA  

if(Precio_Aplicado==0)

Tipo_Precio[r]=Close[r]: Precio usado en el cálculo de la EMA será el precio de cierre.

if(Precio_Aplicado==1)

Tipo_Precio[r]=Open[r]: Precio usado en el cálculo de la EMA será el precio de apertura.

if(Precio_Aplicado==2)

Tipo_Precio[r]=High[r]: Precio usado en el cálculo de la EMA será el precio máximo.

if(Precio_Aplicado==3)

Tipo_Precio[r]=Low[r]: Precio usado en el cálculo de la EMA será el precio mínimo.

if(Precio_Aplicado==4)

Tipo_Precio[r]=(High[r]+Low[r])/2: Precio usado en el cálculo de la EMA será el precio mediano.

if(Precio_Aplicado==5)

Tipo_Precio[r]=(High[r]+Low[r]+Close[r])/3: Precio usado en el cálculo de la EMA será el precio típico.

if(Precio_Aplicado==6)

Tipo_Precio[r]=(High[r]+Low[r]+Close[r]+Close[r])/4: Precio usado en el cálculo de la EMA será el precio ponderado.

Mediante el siguiente código se calcula el valor de la SMA inicial y de los valores subsecuentes de la EMA usando el valor de K y los precios determinados mediante los códigos anteriores.

Debajo de la línea //Cálculo de SMA como primer valor de EMA aparece el código que permite el cálculo del promedio móvil simple (SMA) que se usará como valor inicial para la media móvil exponencial, como muestra la fórmula teórica que explicamos en la sección anterior.

if(i>0)

{

j=i;

n=i-Periodo_EMA;

Suma=0;

for(j;j>=i-Periodo_EMA+1;j–)

Suma=Tipo_Precio[j]+Suma;

EMA[BarsPeriodo_EMA]=Suma/p: Cálculo de la SMA de los primeros periodos (serie inicial de datos usados en el cálculo de la EMA) para obtener el valor inicial de la EMA

}

Este código calcula la SMA que se usará como primer valor del indicador EMA y se calcula con la primera serie de datos del conjunto total de precios empleado en el cálculo del indicador.

Con respecto a los operadores if y for usados en este algoritmo, no vamos a entrar en detalles con respecto a su uso ya que esto queda fuera del alcance de este artículo. Vale decir que se usan para establecer una condición numérica que debe cumplirse y establecer un ciclo de cálculos repetitivos que en este caso permiten calcular la SMA.

Ahora que tenemos el valor de K y la SMA inicial, vamos a calcular los otros valores de la EMA desde el inicio de la serie de datos de precios hasta la barra actual con este último código:

if(i==0)

{

n=0;

}

while(n>=0)

{

EMA[n]=Tipo_Precio[n]*K+EMA[n+1]*(1-K): En esta línea de código se calcula la EMA

n–;

}

En la línea de código anterior resaltada con amarillo, se calcula cada valor de la EMA en todas las barras de precios almacenadas en la memoria de la plataforma hasta la barra de precios actual. El cálculo se realiza tomando la SMA como valor inicial de la EMA. Para el cálculo de los múltiples valores del indicador se utiliza el operador while que sirve para establecer un ciclo repetitivo de cálculos (en cada ciclo se calcula el valor de la EMA usando esa fórmula).

Con esto, damos por terminado el código del indicador EMA. La siguiente línea le indica a la plataforma que la función OnCalculate () ha finalizado y que se espera un resultado al final de la misma, que es el indicador trazado en el gráfico de precios.

return(rates_total);

Una vez que hemos terminado de escribir el código del indicador, el paso final es compilarlo para comprobar que todo está bien.

Compilación del indicador

La compilación significa convertir un código fuente de un programa de MQL4 al lenguaje de la computadora. El resultado es un archivo de programa ejecutable (*.EX4) que se puede iniciar en cualquier plataforma de Metatrader 4.

La compilación consta de varias etapas:

  • Análisis léxico
  • Análisis de sintaxis
  • Análisis semántico
  • Generación de código
  • Optimización de código

Para compilar el código de nuestro indicador y obtener un archivo de programa ejecutable, apretamos el botón F7 o hacemos clic en el botón Compilar como se muestra en la siguiente imagen:

El proceso de compilación tarda fracciones de segundos y si todo sale bien deja listo el indicador para su uso en Metatrader 4 en cualquier gráfico de precios.

El mensaje que muestra MetaEditor debajo de la ventana de edición del indicador es el siguiente:

Ahora, esto no significa necesariamente que el programa no tenga errores o fallas de algún tipo en su código. Lo que quiere decir es que no hay errores de sintaxis en el código y que todas las variables, operadores, fórmulas, etc, fueron usados correctamente. El programa puede estar mal diseñado y ser incapaz de funcionar tal como esperamos y aún así no mostrar ningún error después de la compilación.

Los errores de compilación están marcados con el ícono de Error tanto en la pestaña Errores como en el código correspondiente. No se crea ningún archivo de programa ejecutable (* .EX4) si se detectan errores. Para ir a una línea de código con un error para hacer la corrección, haga doble clic en el error. La línea de código y la columna donde se detecta un error se muestran en las columnas correspondientes.

Las advertencias están marcadas con el icono de Advertencia e indican lugares de posibles errores. Estos son los segmentos del código fuente que pueden malinterpretarse (por ejemplo, un cambio de tipo de valor implícito). Puede ir a dicha línea de código exactamente de la misma manera que en el caso de los errores.

Cuando el compilador encuentra errores o advertencias los muestra de la siguiente forma:

Despliegue del indicador personalizado

Si el compilador de MetaEditor no encuentra ningún error y termina de compilar el indicador personalizado, podemos comenzar a usarlo en la plataforma de inmediato.

El producto final del código que hemos explicado en esta guía es un indicador personalizado que muestra una media móvil EMA en el gráfico junto con una etiqueta en la esquina superior izquierda. Cuando activamos el indicador primero aparece la siguiente ventana de configuración:

Una vez que hemos configurado el indicador, así es como se ve en el gráfico de precios:

El indicador mostrará la EMA en cualquier gráfico de precios, calculada con el tipo de precio que queramos.

Pueden descargar el archivo EMAAlt.mq4 con el código que hemos detallado en esta guía para puedan estudiarlo con más detalle en el siguiente enlace: Indicador EMAAlt para MT4

Conclusiones

En esta guía hemos mostrado el proceso para la creación de un indicador personalizado para MT4, en este caso una media móvil exponencial. No hemos entrado en detalles con respecto a los distintos operadores usados en el código, ya que sería extendernos demasiado y no es el propósito del tutorial, pero hemos tratado de explicar cada paso detalladamente.

El código empleado es solo una forma en que puede programarse un indicador como este en MQL4. Otros programadores con más conocimientos y más experimentados probablemente puedan hacerlo de forma más sencilla y con más detalles.

Para desarrollar indicadores o expert advisors más complejos, es necesario que el programador profundice su conocimiento no solo del mercado y sus instrumentos de análisis, sino también de las distintas funciones, operadores y otras herramientas que ofrece MQL4.

En esta guía solo hemos mostrado una pincelada de lo que se puede hacer con MQL4 y esperamos que sirva como punto de inicio para los que están interesados en el tema del trading algorítmico en las plataformas Metatrader.

¿Quiere crear un indicador personalizado o automatizar sus  sistemas de trading?

  • rcanessa@gmail.com
  • rcascta@hotmail.com