
Desarrollamos un indicador Heiken Ashi personalizado utilizando MQL5
Introducción
Todos necesitamos interpretar gráficos. Las herramientas que ayudarnos en esta tarea incluyen indicadores calculados según los precios, el volumen, otro indicador técnico o una combinación de estos. Tenemos muchos indicadores listos para usar integrados en el terminal comercial, pero si necesitamos añadir algunas funciones que se adapten a nuestro estilo comercial, tendremos que recurrir a soluciones personalizadas.
En este artículo, usaremos la función iCustom y crearemos un indicador personalizado según nuestras condiciones y preferencias. También crearemos un indicador técnico Heiken Ashi personalizado y lo usaremos en sistemas comerciales. Así, hoy abarcaremos los siguientes temas:
- Definición de un indicador personalizado y Heiken Ashi
- Indicador Heiken Ashi simple
- Asesor experto basado en el indicador personalizado Heiken Ashi
- Heiken Ashi - Sistema EMA
- Conclusión
El material del artículo se puede utilizar como muestra para crear indicadores personalizados propios. Usaremos el lenguaje MQL5 (MetaQuotes Language) integrado en la plataforma comercial MetaTrader 5 para escribir los códigos para los indicadores y asesores creados. Si no sabe cómo descargarlos y utilizarlos, lea la sección "Escribiendo el código MQL5 en el MetaEditor" de artículos anteriores.
Indicador personalizado y definición de Heiken Ashi
Como mencioné en la introducción de la sección anterior, un indicador personalizado es una herramienta de análisis técnico que puede crear el usuario usando el lenguaje de programación MQL5. Puede utilizarse en MetaTrader 5 para analizar y comprender los movimientos del mercado y ayudar a tomar decisiones de inversión informadas. Existen muchos indicadores técnicos incorporados de gran utilidad, pero a veces necesitamos analizar y comprender cómo se está desempeñando el mercado según algunas ideas matemáticas, estadísticas o técnicas adicionales cuyos principios no están cubiertos por los indicadores existentes. En estos casos, deberemos crear dicho indicador nosotros mismos, y esta es una de las características más destacadas de la plataforma MetaTrader 5: su capacidad para ayudar al usuario a crear herramientas analíticas o comerciales propias que se adapten a sus preferencias y objetivos específicos.
Veamos los pasos necesarios para crear nuestro propio indicador:
Abra el MetaEditor y seleccione la carpeta Indicators en el Navegador.
Clique en el botón "Crear" para crear un nuevo programa como se muestra en la siguiente imagen
Después de esto, se abrirá una ventana en la que deberá seleccionar el tipo de programa a crear. Seleccione "Indicador personalizado"
Después de clicar en el botón "Siguiente", se abrirá la siguiente ventana con información sobre el indicador. Introduzca el nombre del indicador personalizado aquí y clique en Siguiente.
En las siguientes ventanas ofrecemos información más detallada sobre el indicador.
Tras completar todas las configuraciones y clicar en el botón "Finalizar", se abrirá la ventana del editor.
Veremos cómo desarrollar un indicador propio usando Heiken Ashi como ejemplo. Como es lógico, primero necesitaremos aprender más sobre él. Heiken Ashi supone una técnica de gráficos de velas que se puede utilizar para representar y analizar los movimientos del mercado, y puede usarse en combinación con otras herramientas para proporcionar información detallada sobre la que tomar decisiones comerciales informadas.
Los gráficos Heiken Ashi son similares a los gráficos de velas normales, pero los métodos para calcular las velas son distintos. Como ya sabemos, un gráfico de velas normal calcula los precios basándose en una serie de precios reales (apertura, máximo, mínimo y cierre) de un periodo determinado, pero Heiken Ashi tiene en cuenta los precios similares anteriores (apertura, máximo, mínimo y cierre) al calcular sus velas.
Así es como se calculan los valores de Heiken Ashi:
- Open = (apertura de la vela anterior + cierre de la vela anterior) / 2
- Close = (apertura + cierre + máximo + mínimo de la vela actual) / 4
- High = valor más alto desde el máximo, apertura o cierre del periodo actual
- Low = valor más bajo desde el mínimo, apertura o cierre del periodo actual
Según el cálculo, el indicador construye velas alcistas y bajistas. Los colores de estas velas indicarán la dirección correspondiente del mercado: alcista o bajista. A modo de comparación, a continuación le mostramos las velas japonesas tradicionales y el Heiken Ashi.
La sección superior muestra las velas tradicionales, mientras que la sección inferior muestra el indicador Heiken Ashi, representado como velas azules y rojas que determinan la dirección del mercado. El objetivo del indicador consiste en filtrar y eliminar parte del ruido en los movimientos del mercado suavizando los datos para evitar señales falsas.
Indicador Heiken Ashi simple
Vamos a crear un indicador Heiken Ashi simple para usarlo en MetaTrader 5. El indicador debe verificar constantemente los precios (apertura, máximo, mínimo y cierre) y realizar cálculos para generar los valores haOpen, haHigh, haLow y haClose. Según los cálculos, el indicador debería mostrar los valores en el gráfico como velas de diferentes colores: azul para el movimiento alcista y rojo para el movimiento bajista. Las velas deberán mostrarse en una ventana aparte debajo del gráfico tradicional en forma de subventana.
Veamos todos los pasos que deberemos seguir para crear este indicador personalizado.
Primero definiremos la configuración del indicador especificando los parámetros adicionales a través de los valores #property y el identificador:
- (indicator_separate_window) - muestra el indicador en una ventana separada.
- (indicator_buffers) - número de búferes de cálculo del indicador.
- (indicator_plots) - número de series gráficas en el indicador. Las series gráficas son los estilos de dibujo que se pueden utilizar al crear un indicador personalizado.
- (indicator_typeN) - tipo de construcción gráfica según los valores (ENUM_DRAW_TYPE). N - número de series gráficas que definimos en el último parámetro. Comienza a partir de 1.
- (indicator_colorN) - color de N. N es también el número de series gráficas que hemos definido anteriormente. Comienza a partir de 1.
- (indicator_widthN) - grosor de N o la serie gráfica.
- (indicator_labelN) - establece la etiqueta N de una serie gráfica específica.
#property indicator_separate_window #property indicator_buffers 5 #property indicator_plots 1 #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrBlue, clrRed #property indicator_width1 2 #property indicator_label1 "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
Luego crearemos cinco arrays para cinco búferes del indicador (haOpen, haHigh, haLow, haClose, haColor) de tipo double.
double haOpen[]; double haHigh[]; double haLow[]; double haClose[]; double haColor[];
Dentro de OnInit() esta función se utilizará para inicializar un indicador en ejecución.
int OnInit()
A continuación clasificaremos los búferes del indicador usando un array dinámico unidimensional de tipo double usando la función (SetIndexBuffer). Los parámetros serán los siguientes:
- index - número del búfer de indicador, comenzando desde 0. El número deberá ser menor que el valor declarado en el parámetro (indicator_buffers).
- buffer[] - array declarado en el indicador personalizado.
- data_type - tipo de datos que necesitamos almacenar en el array de indicadores.
SetIndexBuffer(0,haOpen,INDICATOR_DATA); SetIndexBuffer(1,haHigh,INDICATOR_DATA); SetIndexBuffer(2,haLow,INDICATOR_DATA); SetIndexBuffer(3,haClose,INDICATOR_DATA); SetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX);
Luego estableceremos el valor de la propiedad del indicador correspondiente usando la función (IndicatorSetInteger) con una variante de llamada en la que especificaremos el identificador de la propiedad. Los parámetros serán los siguientes:
- prop_id - identificador de propiedad, que puede ser uno de (ENUM_CUSTOMIND_PROPERTY_INTEGER). Indicaremos (INDICATOR_DIGITS).
- prop_value - valor de la propiedad. Indicaremos (_Digits).
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
A continuación, estableceremos el valor de propiedad correspondiente de tipo string con la opción de llamada en la que también especificaremos el identificador de la propiedad. Los parámetros serán los siguientes:
- prop_id - identificador de propiedad, que puede ser uno de (ENUM_CUSTOMIND_PROPERTY_STRING). Especificaremos (INDICATOR_SHORTNAME) para usar un nombre corto para el indicador.
- prop_value - valor de la propiedad. Indicaremos ("Simple Heiken Ashi").
IndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi");
Luego estableceremos el valor de la propiedad double correspondiente del indicador necesario usando la función (PlotIndexSetDouble). Los parámetros serán los siguientes:
- plot_index - índice de construcción gráfica. Indicaremos 0.
- prop_id - uno de los valores (ENUM_PLOT_PROPERTY_DOUBLE). (PLOT_EMPTY_VALUE) - sin representación.
- prop_value - valor de la propiedad.
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
Luego retornaremos (INIT_SUCCEEDED) como parte de la función OnInit() para finalizarla retornando la inicialización exitosa.
return(INIT_SUCCEEDED);
Dentro de la función OnCalculate, que se llama en el indicador para procesar los datos de precio, el tipo de cálculo cambiará según la serie temporal del periodo actual.
int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[])
Ahora crearemos la variable entera start. Le asignaremos el valor más adelante:
int start;
Después usaremos una declaración if para retornar los valores del índice (bajo, alto, abierto y cerrado) y start=1 si prev_calculated es 0, o retornar el valor inicial asignado a (prev_calculated-1):
if(prev_calculated==0) { haLow[0]=low[0]; haHigh[0]=high[0]; haOpen[0]=open[0]; haClose[0]=close[0]; start=1; } else start=prev_calculated-1;
La función for se usa en el ciclo de cálculo principal. La declaración for consta de tres expresiones y declaraciones ejecutables.
Tres expresiones:
- i=start - posición inicial.
- i<rates_total && !IsStopped() - condiciones para finalizar el ciclo. IsStopped() comprueba la parada forzosa del indicador.
- i++ - añadir 1 para obtener una nueva i.
Las operaciones que deberemos realizar cada vez durante el ciclo son:
Cálculo para las cuatro variables de tipo double.
- haOpenVal - valor de apertura de Heiken Ashi.
- haCloseVal - valor de cierre de Heiken Ashi.
- haHighVal - máximo de Heiken Ashi.
- haLowVal - mínimo de Heiken Ashi.
La asignación de los valores calculados en el paso anterior será similar a la siguiente:
- haLow[i]=haLowVal
- haHigh[i]=haHighVal
- haOpen[i]=haOpenVal
- haClose[i]=haCloseVal
Ahora comprobaremos si el valor de apertura de Heiken Ashi es inferior al valor de cierre. En caso afirmativo, el indicador debería dibujar una vela azul y, en caso contrario, una roja.
for(int i=start; i<rates_total && !IsStopped(); i++) { double haOpenVal =(haOpen[i-1]+haClose[i-1])/2; double haCloseVal=(open[i]+high[i]+low[i]+close[i])/4; double haHighVal =MathMax(high[i],MathMax(haOpenVal,haCloseVal)); double haLowVal =MathMin(low[i],MathMin(haOpenVal,haCloseVal)); haLow[i]=haLowVal; haHigh[i]=haHighVal; haOpen[i]=haOpenVal; haClose[i]=haCloseVal; //--- set candle color if(haOpenVal<haCloseVal) haColor[i]=0.0; else haColor[i]=1.0; }
Luego finalizaremos la función retornando (rates_total) como prev_calculated para la siguiente llamada,
return(rates_total);
y compilaremos el código para asegurarnos de que no haya errores. El código completo tendrá el aspecto que sigue:
//+------------------------------------------------------------------+ //| simpleHeikenAshi.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_buffers 5 #property indicator_plots 1 #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrBlue, clrRed #property indicator_width1 2 #property indicator_label1 "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close" double haOpen[]; double haHigh[]; double haLow[]; double haClose[]; double haColor[]; int OnInit() { SetIndexBuffer(0,haOpen,INDICATOR_DATA); SetIndexBuffer(1,haHigh,INDICATOR_DATA); SetIndexBuffer(2,haLow,INDICATOR_DATA); SetIndexBuffer(3,haClose,INDICATOR_DATA); SetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX); IndicatorSetInteger(INDICATOR_DIGITS,_Digits); IndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi"); PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); return(INIT_SUCCEEDED); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { int start; if(prev_calculated==0) { haLow[0]=low[0]; haHigh[0]=high[0]; haOpen[0]=open[0]; haClose[0]=close[0]; start=1; } else start=prev_calculated-1; for(int i=start; i<rates_total && !IsStopped(); i++) { double haOpenVal =(haOpen[i-1]+haClose[i-1])/2; double haCloseVal=(open[i]+high[i]+low[i]+close[i])/4; double haHighVal =MathMax(high[i],MathMax(haOpenVal,haCloseVal)); double haLowVal =MathMin(low[i],MathMin(haOpenVal,haCloseVal)); haLow[i]=haLowVal; haHigh[i]=haHighVal; haOpen[i]=haOpenVal; haClose[i]=haCloseVal; if(haOpenVal<haCloseVal) haColor[i]=0.0; else haColor[i]=1.0; } return(rates_total); }
Después realizar la compilación con éxito, el indicador estará disponible en la carpeta "Indicadores" en la ventana "Navegador", como se muestra a continuación.
Vamos a iniciarlo. Se abrirá una ventana de configuración estándar:
La pestaña "Colores" mostrará la configuración por defecto: azul para movimiento ascendente, rojo para movimiento descendente. Los valores se pueden modificar.
Después de clicar en OK, el indicador se adjuntará al gráfico y tendrá el aspecto siguiente:
Como podemos ver, el indicador funcionará en una subventana separada. Las velas azules y rojas indicarán la dirección del precio (alcista y bajista). Ahora tenemos nuestro propio indicador creado en MetaTrader 5, y podemos usarlo en cualquier sistema comercial. Esto es exactamente lo que haremos ahora.
Asesor experto basado en el indicador personalizado Heiken Ashi
En este apartado aprenderemos a utilizar los indicadores personalizados en un asesor experto. Para ello, crearemos un sistema Heiken Ashi simple que pueda mostrarnos los precios del indicador (apertura, máximo, mínimo y cierre) ya que sabemos que estos son diferentes de los precios reales calculados por el indicador.
Vamos a crear un asesor. Código completo:
//+------------------------------------------------------------------+ //| heikenAshiSystem.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" int heikenAshi; int OnInit() { heikenAshi=iCustom(_Symbol,_Period,"My Files\\Heiken Ashi\\simpleHeikenAshi"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print("Heiken Ashi System Removed"); } void OnTick() { double heikenAshiOpen[], heikenAshiHigh[], heikenAshiLow[], heikenAshiClose[]; CopyBuffer(heikenAshi,0,0,1,heikenAshiOpen); CopyBuffer(heikenAshi,1,0,1,heikenAshiHigh); CopyBuffer(heikenAshi,2,0,1,heikenAshiLow); CopyBuffer(heikenAshi,3,0,1,heikenAshiClose); Comment("heikenAshiOpen ",DoubleToString(heikenAshiOpen[0],_Digits), "\n heikenAshiHigh ",DoubleToString(heikenAshiHigh[0],_Digits), "\n heikenAshiLow ",DoubleToString(heikenAshiLow[0],_Digits), "\n heikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits)); }
Diferencias en este código:
Tipo de programa: asesor. El diseño del programa será diferente porque consta de tres partes, concretamente:
- int OnInit() - ejecuta el inicio del asesor con el tipo recomendado que retorna un valor entero.
- void OnDeinit - desinicializa el funcionamiento de un asesor que no retorna ningún valor.
- void OnTick() - procesa una nueva cotización en cada tick, no retorna un valor.
Fuera de las funciones anteriores y antes de las mismas, crearemos una variable entera (heikenAshi)
int heikenAshi;
Dentro del ámbito de OnInit(), asignaremos el valor de la función iCustom a la variable heikenAshi. La función iCustom retornará el identificador del indicador personalizado, que aquí será Simple Heiken Ashi, pero puede usar cualquier indicador personalizado en la carpeta Indicadores. Parámetros:
- symbol - nombre del símbolo, usaremos (_Symbol) para el símbolo actual.
- period - periodo de tiempo, utilizaremos (_Period) para el periodo de tiempo actual.
- name - nombre del indicador personalizado que indica la ruta al mismo en la carpeta "Indicadores". Aquí usaremos My Files\\Heiken Ashi\\simpleHeikenAshi.
Luego finalizaremos la función retornando (INIT_SUCCEEDED) para una inicialización exitosa.
int OnInit() { heikenAshi=iCustom(_Symbol,_Period,"My Files\\Heiken Ashi\\simpleHeikenAshi"); return(INIT_SUCCEEDED); }
Dentro de la función OnDeinit(), usaremos la función print para indicar que el asesor ha sido eliminado.
void OnDeinit(const int reason) { Print("Heiken Ashi System Removed"); }
Dentro de la función OnTick(), hemos hecho lo siguiente para finalizar nuestro código:
Hemos creado cuatro variables de tipo doble para los precios de Heiken Ashi (Open, High, Low y Close).
double heikenAshiOpen[], heikenAshiHigh[], heikenAshiLow[], heikenAshiClose[];
Luego hemos obtenido los datos de los búferes del indicador personalizado utilizando la función CopyBuffer. Parámetros:
- Indicator_handle - manejador del indicador que hemos utilizado (heikenAshi).
- buffer_num - número del búfer de indicador que hemos utilizado (0 para apertura, 1 para máximo, 2 para mínimo y 3 para cierre).
- start_pos - primera posición del elemento a copiar, hemos usado 0 para el elemento actual.
- count - volumen de datos para copiar, hemos usado 1. Eso será suficiente aquí.
- buffer[] - array usado para copiar. Hemos utilizado (heikenAshiOpen para la apertura, heikenAshiHigh para el máximo, heikenAshiLow para el mínimo y heikenAshiClose para el cierre).
Luego hemos recibido un comentario en el gráfico con los precios actuales de Heiken Ashi (apertura, máximo, mínimo y cierre) utilizando la función de comentario:
Comment("heikenAshiOpen ",DoubleToString(heikenAshiOpen[0],_Digits), "\n heikenAshiHigh ",DoubleToString(heikenAshiHigh[0],_Digits), "\n heikenAshiLow ",DoubleToString(heikenAshiLow[0],_Digits), "\n heikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits));
Tras compilar y ejecutar este código sin errores, podemos encontrar el asesor adjunto al gráfico. Es posible obtener la misma señal en el siguiente ejemplo:
Como podemos ver, los precios de los indicadores se muestran como un comentario en la esquina superior izquierda del gráfico.
Heiken Ashi - Sistema EMA
En este apartado añadiremos otra herramienta técnica para ver si el resultado es mejor o no. La idea consiste en filtrar las señales de los indicadores personalizados utilizando una media móvil exponencial con precios. Existen muchas formas de hacer esto: podemos crear otro indicador personalizado para EMA si queremos añadir más funciones a esta. Luego podremos usarlo en el asesor como iCustom de la misma manera que lo hemos hecho para obtener las señales deseadas. También podemos crear un indicador suavizado, realizando para ello el suavizado de los valores del indicador y luego usando nuestras señales. Podemos usar la función iMA incorporada en nuestro asesor para obtener señales del mismo. Por su simplicidad, aquí usaremos este método.
Necesitamos permitir que el asesor verifique continuamente los valores de las dos EMA actuales (rápida y lenta), la EMA rápida anterior y el precio de cierre de Heiken Ash para determinar las posiciones de cada valor. Si el valor anterior de heikenAshiClose es mayor que el array fastEMA anterior, y el valor fastEMA actual es mayor que el valor actual de SlowEMA, el asesor debería retornar una señal de compra y estos valores deberían mostrarse en el gráfico. Si el anterior valor de heikenAshiClose está por debajo del array fastEMA anterior y el valor de fastEMA actual está por debajo del valor actual de SlowEMA, el asesor debería retornar una señal de venta y estos valores deberían mostrarse en el gráfico.
Aquí tenemos el código completo para crear un asesor:
//+------------------------------------------------------------------+ //| heikenAsh-EMASystem.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" input int fastEMASmoothing=9; // Fast EMA Period input int slowEMASmoothing=18; // Slow EMA Period int heikenAshi; double fastEMAarray[], slowEMAarray[]; int OnInit() { heikenAshi=iCustom(_Symbol,_Period,"My Files\\Heiken Ashi\\simpleHeikenAshi"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print("Heiken Ashi-EMA System Removed"); } void OnTick() { double heikenAshiOpen[], heikenAshiHigh[], heikenAshiLow[], heikenAshiClose[]; CopyBuffer(heikenAshi,0,0,3,heikenAshiOpen); CopyBuffer(heikenAshi,1,0,3,heikenAshiHigh); CopyBuffer(heikenAshi,2,0,3,heikenAshiLow); CopyBuffer(heikenAshi,3,0,3,heikenAshiClose); int fastEMA = iMA(_Symbol,_Period,fastEMASmoothing,0,MODE_SMA,PRICE_CLOSE); int slowEMA = iMA(_Symbol,_Period,slowEMASmoothing,0,MODE_SMA,PRICE_CLOSE); ArraySetAsSeries(fastEMAarray,true); ArraySetAsSeries(slowEMAarray,true); CopyBuffer(fastEMA,0,0,3,fastEMAarray); CopyBuffer(slowEMA,0,0,3,slowEMAarray); if(heikenAshiClose[1]>fastEMAarray[1]) { if(fastEMAarray[0]>slowEMAarray[0]) { Comment("Buy Signal", "\nfastEMA ",DoubleToString(fastEMAarray[0],_Digits), "\nslowEMA ",DoubleToString(slowEMAarray[0],_Digits), "\nprevFastEMA ",DoubleToString(fastEMAarray[1],_Digits), "\nprevHeikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits)); } } if(heikenAshiClose[1]<fastEMAarray[1]) { if(fastEMAarray[0]<slowEMAarray[0]) { Comment("Sell Signal", "\nfastEMA ",DoubleToString(fastEMAarray[0],_Digits), "\nslowEMA ",DoubleToString(slowEMAarray[0],_Digits), "\nprevFastEMA ",DoubleToString(fastEMAarray[1],_Digits), "\nheikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits)); } } }
Qué ha cambiado en el código con respecto al anterior:
Crearemos datos de entrada personalizados para establecer el periodo de la EMA rápida y el periodo de la EMA lenta según las preferencias del usuario.
input int fastEMASmoothing=9; // Fast EMA Period input int slowEMASmoothing=18; // Slow EMA Period
Luego crearemos dos arrays para fastEMA y slowEMA,
double fastEMAarray[], slowEMAarray[];
y estableceremos en 3 la cantidad de datos copiados en CopyBuffer para obtener los valores de cierre anteriores del indicador Heiken Ashi.
CopyBuffer(heikenAshi,0,0,3,heikenAshiOpen); CopyBuffer(heikenAshi,1,0,3,heikenAshiHigh); CopyBuffer(heikenAshi,2,0,3,heikenAshiLow); CopyBuffer(heikenAshi,3,0,3,heikenAshiClose);
Determinaremos la EMA rápida y lenta usando la función iMA incorporada, que devuelve el identificador del indicador de media móvil. Parámetros:
- symbol - nombre del símbolo, usaremos (_Symbol) para el símbolo actual.
- period - tiempo que utilizamos (_Period) para la hora actual.
- ma_period - period para suavizar el valor promedio que utilizamos (fastEMASmoothing y slowEMASmoothing).
- ma_shift - cambio de indicador, usamos 0.
- ma_method - tipo de media móvil, usamos MODE_SMA para una media móvil simple.
- applied_price - tipo de precio requerido para los cálculos, usamos PRICE_CLOSE.
int fastEMA = iMA(_Symbol,_Period,fastEMASmoothing,0,MODE_SMA,PRICE_CLOSE); int slowEMA = iMA(_Symbol,_Period,slowEMASmoothing,0,MODE_SMA,PRICE_CLOSE);
Utilizaremos la función ArraySetAsSeries para configurar el indicador AS_SERIES. Parámetros:
- array[] - array que utilizamos (fastEMAarray y slowEMA).
- flag - dirección de indexación del array, usamos true.
ArraySetAsSeries(fastEMAarray,true); ArraySetAsSeries(slowEMAarray,true);
Luego obtendremos los datos del búfer del indicador EMA usando la función CopyBuffer.
CopyBuffer(fastEMA,0,0,3,fastEMAarray); CopyBuffer(slowEMA,0,0,3,slowEMAarray);
Condiciones para retornar señales usando la declaración if:
En caso de una señal de compra
Si heikenAshiClose anterior > el array fastEMA anterior y el array fastEMA actual > el array slowEMA actual, el asesor debería retornar una señal de compra y los siguientes valores:
- fastEMA
- slowEMA
- prevFastEMA
- prevHeikenAshiClose
if(heikenAshiClose[1]>fastEMAarray[1]) { if(fastEMAarray[0]>slowEMAarray[0]) { Comment("Buy Signal", "\nfastEMA ",DoubleToString(fastEMAarray[0],_Digits), "\nslowEMA ",DoubleToString(slowEMAarray[0],_Digits), "\nprevFastEMA ",DoubleToString(fastEMAarray[1],_Digits), "\nprevHeikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits)); }
Con una señal de venta:
Si heikenAshiClose anterior < el array fastEMA anterior y el array fastEMA actual < el array slowEMA actual, el asesor debería retornar una señal de venta y los valores de precio:
- fastEMA
- slowEMA
- prevFastEMA
- prevHeikenAshiClose
if(heikenAshiClose[1]<fastEMAarray[1]) { if(fastEMAarray[0]<slowEMAarray[0]) { Comment("Sell Signal", "\nfastEMA ",DoubleToString(fastEMAarray[0],_Digits), "\nslowEMA ",DoubleToString(slowEMAarray[0],_Digits), "\nprevFastEMA ",DoubleToString(fastEMAarray[1],_Digits), "\nheikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits)); } }
Tras compilar el código y ejecutarlo, podremos obtener nuestras señales como se muestra en los siguientes ejemplos de prueba.
Si hay una señal de compra:
Como podemos ver en el gráfico anterior, en la esquina superior izquierda tenemos como comentario la siguiente señal:
- Señal de compra
- fastEMA
- prevFastEMA
- prevHeikenAshiClose
Si hay una señal de venta:
Como señal en el gráfico tenemos los valores siguientes:
- Señal de venta
- fastEMA
- prevFastEMA
- prevHeikenAshiClose
Conclusión
Si ha entendido todo lo que hemos comentado en este artículo, podrá crear su propio indicador Heiken Ashi o incluso añadir algunas características adicionales según sus preferencias. Esto hará más fácil leer los gráficos y tomar decisiones efectivas. Además, podrá utilizar el indicador creado en sus sistemas comerciales como parte de los asesores, ya que lo hemos mencionado y utilizado en dos sistemas comerciales como ejemplo.
- Sistema Heiken Ashi
- Sistema Heiken Ashi-EMA
Espero que este artículo le resulte útil y le ayude a alcanzar sus objetivos comerciales. También espero que intente aplicar lo aprendido en este artículo, ya que le será de gran ayuda para entrenar sus habilidades de programación, y la práctica supone un factor esencial en el aprendizaje. Tenga en cuenta que debe probar todo lo aprendido en este artículo u otros recursos antes de usar sus conocimientos en el comercio real. Este artículo tiene fines exclusivamente educativos, por lo que el lector deberá tener cuidado y mostrar prudencia.
En mi perfil podrá encontrar los enlaces a mis otros artículos. Espero que también los encuentre útiles.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/12510





- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso