Desarrollamos el indicador True Strength Index personalizado utilizando MQL5
Introducción
Si se usan correctamente, los indicadores técnicos pueden resultar muy útiles, ya que pueden ofrecer información adicional que resulta difícil de detectar simplemente observando la acción del precio. Existen muchos indicadores técnicos ya preparados que podemos usar, pero a veces necesitamos personalizarlos para que nos proporcionen información específica o bien tendremos que crear un nuevo indicador basado en nuestras ideas. Hay una manera de crear estos indicadores personalizados en MQL5 y utilizarlos en la plataforma comercial MetaTrader 5. En este artículo le mostraré cómo crear un TSI desde cero. Asimismo, estudiaremos los detalles de este indicador y veremos cómo calcularlo en nuestro código. También aprenderemos cómo podemos usar este indicador personalizado en un sistema comercial creando un asesor experto. Todas estas cuestiones se tratarán en los siguientes apartados:
- Definición de True Strength Index (TSI)
- Indicador TSI simple personalizado
- Asesor TSI personalizado
- Asesor TSI System
- Conclusión
Una vez dominemos los temas mencionados, podremos usar e interpretar el indicador True Strength Index, y también calcularlo y convertirlo en código como indicador personalizado en MQL5 para posteriormente usarlo en MetaTrader 5. Asimismo, podremos implementar el indicador en otros sistemas comerciales o asesores. Si desea desarrollar sus habilidades de programación, le animo a que escriba el código por sí mismo, ya que esta práctica supone un paso muy importante en cualquier proceso de aprendizaje. Usaremos MetaTrader 5 para escribir el código MQL5 en su IDE integrado en el terminal comercial MetaTrader 5. Si no tiene la plataforma o no sabe cómo descargarla y usarla, consulte la sección "Escribiendo el código MQL5 en el MetaEditor" en varios de mis artículos anteriores.
Definición de True Strength Index (TSI)
En esta sección veremos el indicador técnico True Strength Index (TSI), diseñado en su día por William Blau. El indicador mide el impulso de la acción del precio, es decir, la fuerza del instrumento. Este oscila alrededor de la línea cero, por eso se trata de un oscilador de impulso. Podemos utilizar una línea de señal junto con él para generar señales de compra o venta adicionales basadas en la intersección de estas líneas. No obstante, solo podremos recibir señales desde la línea TSI, valiéndonos de su intersección con el nivel cero. Si está por encima de la línea cero, indicará un impulso alcista, y si está por debajo, indicará un impulso bajista. El indicador se puede usar para detectar áreas de sobrecompra y sobreventa, así como para detectar divergencias alcistas y bajistas. Como sabemos que necesitamos confirmar sus señales para aumentar el peso de las pruebas, será mejor usarlo en combinación con otras herramientas técnicas que deberíamos utilizar en el mismo contexto de la acción del precio para una mejor comprensión.
Veamos ahora cómo calcular este indicador. El cálculo se realiza en varias etapas, concretamente:
Cálculo del impulso doblemente suavizado:
- Calculamos el impulso (cambio de precio) restando el precio anterior del actual
- Calculamos el primer suavizado obteniendo la EMA de 25 periodos del impulso calculado
- Calculamos el segundo suavizado obteniendo la EMA de 13 periodos del primer suavizado (EMA de 25 periodos del impulso calculado)
Cálculo del impulso absoluto doblemente suavizado:
- Calculamos el impulso absoluto restando el precio absoluto anterior del precio absoluto actual
- Calculamos el primer suavizado obteniendo la EMA de 25 periodos del impulso absoluto calculado
- Calculamos el segundo suavizado obteniendo la EMA de 13 periodos del primer suavizado (EMA de 25 periodos del impulso absoluto calculado)
Cálculo del TSI = 100*(Impulso doble suavizado / Impulso absoluto doble suavizado)
El resultado de este cálculo será una línea que fluctuará alrededor de cero, midiendo el impulso de la acción del precio e identificando las áreas de sobrecompra y sobreventa.
Indicador TSI simple personalizado
El lenguaje de programación MQL5 tiene muchos indicadores técnicos predefinidos que podemos usar en nuestros sistemas utilizando la función predefinida. Ya hemos mencionado muchos de estos indicadores en artículos anteriores de la serie al analizar cómo podemos desarrollar un sistema comercial. Puede consultar los artículos anteriores para buscar información útil. Ahora la pregunta es cómo podemos crear un indicador si no existe en el paquete de entrega estándar de la plataforma, e incluso si existe, cómo podemos crear un indicador personalizado para obtener las señales o activadores deseados. La respuesta corta es que debemos crear nuestro propio indicador utilizando un lenguaje de programación básico. Eso es lo que haremos aquí:
aprenderemos a crear un indicador TSI personalizado usando MQL5. Luego utilizaremos sus capacidades en otros sistemas o asesores. Para crear este indicador personalizado, deberemos cumplir las siguientes etapas.
Al crear parámetros adicionales usando #property, indicaremos al lado el valor del identificador. Tendremos que especificar los siguientes parámetros:
- (indicator_separate_window) — muestra el indicador en una ventana aparte.
- (indicator_buffers) — número de búferes del indicador. Indicaremos (8).
- (indicator_plots) — especifica el número de series gráficas del indicador. Indicaremos (1).
- (indicator_label1) — para establecer la etiqueta del número de serie gráfica, especificaremos (TSI).
- (indicator_type1) — para indicar el tipo de construcción gráfica especificando un valor de los valores ENUM_DRAW_TYPE, especificaremos (DRAW_LINE).
- (indicator_color1) — para especificar el color de la línea del indicador mostrada, especificaremos (clrBlue).
- (indicator_style1) — para especificar el estilo de la línea del indicador, especificaremos (STYLE_SOLID).
- (indicator_width1) — para especificar el grosor de la línea del indicador, especificaremos (3).
#property indicator_separate_window #property indicator_buffers 8 #property indicator_plots 1 #property indicator_label1 "TSI" #property indicator_type1 DRAW_LINE #property indicator_color1 clrBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 3
Asimismo, necesitaremos incluir el archivo MovingAverage.mqh para utilizar su componente en nuestros cálculos. Este archivo se activará en Include usando el comando #include. Asegúrese de que los nombres de los archivos coincidan.
#include <MovingAverages.mqh>
También necesitaremos establecer los dos periodos de suavizado que usaremos al calcular el indicador, utilizando la clase de datos de entrada para que el usuario introduzca estos valores si necesita actualizar los valores predeterminados que están especificados en el programa. Después de esto, definiremos el tipo de datos de las variables (InpSmPeriod1, InpSmPeriod2) que necesitamos declarar usando uint, que es un número entero sin signo. Luego estableceremos (25) InpSmPeriod1 y (13) InpSmPeriod2 como valores predeterminados.
input uint InpSmPeriod1 = 25; // Smoothing period 1 input uint InpSmPeriod2 = 13; // Smoothing period 2
A continuación, crearemos dos variables enteras para los periodos de suavizado (smperiod1,smperiod2),
int smperiod1; int smperiod2;
y crearemos siete arrays para los búferes de indicador
double indBuff[]; double momBuff[]; double momSmBuff1[]; double momSmBuff2[]; double absMomBuff[]; double absMomSmBuff1[]; double absMomSmBuff2[];
Realizaremos los siguientes pasos dentro de la función OnInit():
Primero declararemos las variables (smperiod1,smperiod2), retornando el valor 2 si los parámetros de entrada del usuario InpSmPeriod1 e InpSmPeriod2 son menores que 2, o devolviendo los valores InpSmPeriod1 e InpSmPeriod2 en caso contrario.
smperiod1=int(InpSmPeriod1<2 ? 2 : InpSmPeriod1); smperiod2=int(InpSmPeriod2<2 ? 2 : InpSmPeriod2);
Luego conectaremos los búferes de indicador a los arrays usando la función (SetIndexBuffer). Los parámetros serán los siguientes:
index: número del búfer del indicador, y números del 0 al 7 en el programa.
buffer[]: array declarado en el indicador personalizado.
data_type: tipo de datos almacenados en el array de indicadores.
SetIndexBuffer(0,indBuff,INDICATOR_DATA); SetIndexBuffer(2,momBuff,INDICATOR_CALCULATIONS); SetIndexBuffer(3,momSmBuff1,INDICATOR_CALCULATIONS); SetIndexBuffer(4,momSmBuff2,INDICATOR_CALCULATIONS); SetIndexBuffer(5,absMomBuff,INDICATOR_CALCULATIONS); SetIndexBuffer(6,absMomSmBuff1,INDICATOR_CALCULATIONS); SetIndexBuffer(7,absMomSmBuff2,INDICATOR_CALCULATIONS);
Al establecer el valor de la propiedad de indicador correspondiente, esta propiedad del indicador (valor prop) deberá ser de tipo string usando la función (IndicatorSetString) con una opción de llamada que especifique solo el identificador de la propiedad. Este paso consiste en establecer un nombre breve para el indicador y definir los periodos que se mostrarán en la parte superior izquierda de la ventana del indicador. Sus parámetros son:
- prop_id: identificador de la propiedad de indicador incluida en la enumeración (ENUM_CUSTOMIND_PROPERTY_STRING). En nuestro programa será (INDICATOR_SHORTNAME).
- prop_value: valor de propiedad, será de tipo string. En nuestro caso, este será "True Strength Index ("+(string)smperiod1+","+(string)smperiod2+")".
IndicatorSetString(INDICATOR_SHORTNAME,"True Strength Index ("+(string)smperiod1+","+(string)smperiod2+")");
Luego estableceremos otro valor de la propiedad de indicador en un tipo de datos entero para normalizar el valor de indicador según el número de decimales usando (IndicatorSetInteger) con una opción de compra que especifique solo el identificador de propiedad. Parámetros:
- prop_id: identificador de propiedad de indicador incluida en la enumeración (ENUM_CUSTOMIND_PROPERTY_INTEGER). En nuestro programa será (INDICATOR_DIGITS).
- prop_value: valor de propiedad, será un tipo de datos entero. Será Digits().
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
A continuación estableceremos el indicador AS_SERIES para el array usando (ArraySetAsSeries).
ArraySetAsSeries(indBuff,true); ArraySetAsSeries(momBuff,true); ArraySetAsSeries(momSmBuff1,true); ArraySetAsSeries(momSmBuff2,true); ArraySetAsSeries(absMomBuff,true); ArraySetAsSeries(absMomSmBuff1,true); ArraySetAsSeries(absMomSmBuff2,true);
Después de la función OnCalculate
- Después configuraremos el indicador AS_SERIES para el array cerrado de OnCalculate y verificaremos si rate_total es menor que 2 para retornar 0,
- y crearemos una variable entera (limit) igual a (rates_total-prev_calculated).
- Luego comprobaremos si la variable límite es mayor que 1. En este caso, deberemos los pasos siguientes:
- Actualizaremos la variable limit con el resultado (rates_total - 2).
- Después inicializaremos los arrays numéricos de tipo double con un valor dado usando la función (ArrayInitialize). Sus parámetros serán array[] para indicar el array numérico que se inicializará, y el parámetro value para indicar el nuevo valor establecido.
ArraySetAsSeries(close,true); if(rates_total<2) return 0; int limit=rates_total-prev_calculated; if(limit>1) { limit=rates_total-2; ArrayInitialize(indBuff,EMPTY_VALUE); ArrayInitialize(momBuff,0); ArrayInitialize(momSmBuff1,0); ArrayInitialize(momSmBuff2,0); ArrayInitialize(absMomBuff,0); ArrayInitialize(absMomSmBuff1,0); ArrayInitialize(absMomSmBuff2,0); }
Luego crearemos un ciclo para actualizar momBuff[i], absMomBuff[i]. Nuevas funciones utilizadas en esta etapa:
- una operación de ciclo (for) con tres expresiones y una declaración ejecutable.
- IsStopped() para comprobar si el programa mql5 ha sido forzado a finalizar.
- MathAbs retorna el valor absoluto (módulo) y podemos usar la función febs() para obtener el mismo resultado.
for(int i=limit; i>=0 && !IsStopped(); i--) { momBuff[i]=close[i]-close[i+1]; absMomBuff[i]=MathAbs(momBuff[i]); }
Realizaremos la comprobación usando la función ExponentialMAOnBuffer del archivo de inclusión (MovingAverage).
if(ExponentialMAOnBuffer(rates_total,prev_calculated,0,smperiod1,momBuff,momSmBuff1)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,0,smperiod1,absMomBuff,absMomSmBuff1)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,smperiod1,smperiod2,momSmBuff1,momSmBuff2)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,smperiod1,smperiod2,absMomSmBuff1,absMomSmBuff2)==0) return 0;
Luego crearemos otro ciclo para actualizar la variable indBuff[i] usando la función for
for(int i=limit; i>=0 && !IsStopped(); i--) indBuff[i]=(absMomSmBuff2[i]!=0 ? 100.0*momSmBuff2[i]/absMomSmBuff2[i] : 0);
Al final del programa existe una función de retorno (rates_total).
return(rates_total);
Ya hemos completado el código para crear nuestro indicador TSI personalizado: usted también podrá editar sus preferencias en su código para lograr configuraciones adicionales. El código completo del indicador tiene el aspecto siguiente:
//+------------------------------------------------------------------+ //| simple TSI.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 8 #property indicator_plots 1 #property indicator_label1 "TSI" #property indicator_type1 DRAW_LINE #property indicator_color1 clrBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 3 #include <MovingAverages.mqh> input uint InpSmPeriod1 = 25; // Smoothing period 1 input uint InpSmPeriod2 = 13; // Smoothing period 2 int smperiod1; int smperiod2; double indBuff[]; double momBuff[]; double momSmBuff1[]; double momSmBuff2[]; double absMomBuff[]; double absMomSmBuff1[]; double absMomSmBuff2[]; int OnInit() { smperiod1=int(InpSmPeriod1<2 ? 2 : InpSmPeriod1); smperiod2=int(InpSmPeriod2<2 ? 2 : InpSmPeriod2); SetIndexBuffer(0,indBuff,INDICATOR_DATA); SetIndexBuffer(2,momBuff,INDICATOR_CALCULATIONS); SetIndexBuffer(3,momSmBuff1,INDICATOR_CALCULATIONS); SetIndexBuffer(4,momSmBuff2,INDICATOR_CALCULATIONS); SetIndexBuffer(5,absMomBuff,INDICATOR_CALCULATIONS); SetIndexBuffer(6,absMomSmBuff1,INDICATOR_CALCULATIONS); SetIndexBuffer(7,absMomSmBuff2,INDICATOR_CALCULATIONS); IndicatorSetString(INDICATOR_SHORTNAME,"True Strength Index ("+(string)smperiod1+","+(string)smperiod2+")"); IndicatorSetInteger(INDICATOR_DIGITS,Digits()); ArraySetAsSeries(indBuff,true); ArraySetAsSeries(momBuff,true); ArraySetAsSeries(momSmBuff1,true); ArraySetAsSeries(momSmBuff2,true); ArraySetAsSeries(absMomBuff,true); ArraySetAsSeries(absMomSmBuff1,true); ArraySetAsSeries(absMomSmBuff2,true); 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[]) { ArraySetAsSeries(close,true); if(rates_total<2) return 0; int limit=rates_total-prev_calculated; if(limit>1) { limit=rates_total-2; ArrayInitialize(indBuff,EMPTY_VALUE); ArrayInitialize(momBuff,0); ArrayInitialize(momSmBuff1,0); ArrayInitialize(momSmBuff2,0); ArrayInitialize(absMomBuff,0); ArrayInitialize(absMomSmBuff1,0); ArrayInitialize(absMomSmBuff2,0); } for(int i=limit; i>=0 && !IsStopped(); i--) { momBuff[i]=close[i]-close[i+1]; absMomBuff[i]=MathAbs(momBuff[i]); } if(ExponentialMAOnBuffer(rates_total,prev_calculated,0,smperiod1,momBuff,momSmBuff1)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,0,smperiod1,absMomBuff,absMomSmBuff1)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,smperiod1,smperiod2,momSmBuff1,momSmBuff2)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,smperiod1,smperiod2,absMomSmBuff1,absMomSmBuff2)==0) return 0; for(int i=limit; i>=0 && !IsStopped(); i--) indBuff[i]=(absMomSmBuff2[i]!=0 ? 100.0*momSmBuff2[i]/absMomSmBuff2[i] : 0); return(rates_total); }
Tras compilar este código sin errores, encontraremos el indicador entre los disponibles en la carpeta "Indicadores" del navegador. Al arrastrarlo al gráfico deseado, veremos la ventana de parámetros del indicador:
Entonces tendremos dos parámetros de entrada que el usuario podrá definir, además de los valores predeterminados: 25 para el periodo de suavizado 1, y 13 para el periodo de suavizado 2. Sin embargo, como ya hemos mencionado, el usuario podrá editarlos según sus preferencias.
En la imagen anterior, en la pestaña de colores, podemos ver que el usuario puede seleccionar el color, la anchura y el estilo de la línea TSI. Tras configurar los parámetros necesarios y el estilo del indicador, este se verá así:
Como podemos ver en el gráfico anterior, la línea del indicador TSI se encuentra en una ventana aparte bajo de los precios y fluctúa alrededor de cero, y además tenemos la etiqueta del indicador, sus periodos de suavizado y el valor del indicador.
Asesor TSI personalizado
En esta sección, veremos lo sencillo que es utilizar un indicador en un sistema automatizado para que pueda generar una determinada señal o acción al activarse una determinada condición. Comenzaremos creando un asesor muy simple que generará un comentario en el gráfico con el valor TSI actual y luego desarrollaremos un asesor que ejecutará instrucciones más complejas.
A continuación detallaremos los pasos necesarios para crear un asesor:
- Creamos una variable entera (TSI).
- Definimos TSI utilizando la función iCustom para devolver el descriptor del indicador y sus parámetros:
- symbol — nombre del símbolo; para nosotros será _Symbol, es decir, calcularemos el indicador según el símbolo del gráfico actual.
- period — marco temporal para el cálculo; el valor _period significa que el indicador se calculará en el marco temporal actual.
- name — ruta al indicador personalizado.
- Mostrar el texto "TSI System Removed" en OnDeinit (TSI System eliminado) después de eliminar el asesor.
- Crearemos el array tsiVal[]
- Obtener los datos del búfer del indicador TSI usando la función CopyBuffer con la opción de llamar según la primera posición y el número de elementos requeridos. Los parámetros serán los siguientes:
- indicator_handle — manejador de indicador retornado que usaremos (TSI).
- buffer_num — número de búfer de indicador, lo estableceremos en (0).
- start_pos — posición inicial para copiar, especificaremos (0).
- count — cantidad de datos a copiar, especificaremos (1).
- buffer[]: array a copiar, especificaremos (tsiVal).
- Usando la función Comment para mostrar el valor TSI actual convertido a un valor string utilizando la función (DoubleToString) con parámetros value para indicar el valor TSI actual y para indicar el número de dígitos, nosotros usaremos (_Digits) para el valor actual.
El código completo de este sistema tendrá el aspecto siguiente:
//+------------------------------------------------------------------+ //| customSimpleTSI-EA.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 TSI; int OnInit() { TSI=iCustom(_Symbol,_Period,"My Files\\TSI\\simpleTSI"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print("TSI System Removed"); } void OnTick() { double tsiVal[]; CopyBuffer(TSI,0,0,1,tsiVal); Comment("TSI Value ",DoubleToString(tsiVal[0],_Digits)); }
Una vez que este código de error se compile y ejecute, se adjuntará al gráfico. Aquí tenemos un ejemplo de prueba de una señal basada en esta estrategia:
Como podemos ver, el valor TSI actual se indica en la esquina superior izquierda del gráfico. Si queremos asegurarnos de que la señal sea la misma que la nuestra según el indicador, podemos adjuntar un asesor y especificar el indicador como valores al mismo tiempo. Vamos a asegurarnos de que todo funcione:
Como podemos ver en la esquina superior derecha, tenemos un asesor adjunto, y su señal aparece en la esquina superior izquierda con el valor TSI actual. Al mismo tiempo, tenemos el indicador TSI insertado en el gráfico como una ventana aparte debajo de los precios, y su valor es mayor. Su línea en la esquina izquierda coincide con la señal del asesor.
Asesor TSI System
En esta parte, desarrollaremos un asesor basado en el indicador TSI personalizado creado para recibir señales basadas en una estrategia específica. Tenga en cuenta que la estrategia que vamos a analizar tiene fines únicamente educativos. En cualquier caso, requerirá de una cierta optimización, como cualquier otra. Por consiguiente, deberá probarla antes de usarla en una cuenta real para asegurarse de que le resulte útil.
Nosotros usaremos nuestro propio indicador TSI en combinación con dos medias móviles para generar señales de compra y venta basadas en una estrategia específica:
Además de nuestro indicador TSI personalizado, usaremos dos medias móviles simples (MA): una rápida con un periodo de 10 y otra lenta con un periodo de 20. Si el valor anterior de la MA rápida es menor que la MA lenta anterior y al mismo tiempo la MA rápida actual es mayor que la MA lenta actual, esto significará que tenemos un cruce de MA alcista. Luego comprobaremos si el valor TSI actual es superior a cero. Necesitaremos obtener la señal de compra como comentario en el gráfico. Si el valor anterior de la MA rápida es mayor que la MA lenta anterior y al mismo tiempo la MA rápida actual es menor que la MA lenta actual, esto significará que tenemos un cruce de MA bajista. Luego comprobaremos si el valor TSI actual es inferior a cero. Necesitaremos obtener la señal de venta como comentario en el gráfico.
Esquemáticamente:
Si fastMA[1]>slowMA[1] && fastMA[0]<slowMA[0] && tsiVal[0]<0 ==> Señal de venta
El código completo para crear un sistema comercial de este tipo tendrá el aspecto que sigue:
//+------------------------------------------------------------------+ //| TSI System EA.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 ENUM_MA_METHOD inpMAType = MODE_SMA; //Moving Average Type input ENUM_APPLIED_PRICE inpPriceType = PRICE_CLOSE; //Price type input int inpFastMAPeriod = 10; // Fast moving average period input int inpSlowMAPeriod = 20; //Slow moving average period int tsi; double fastMAarray[], slowMAarray[]; int OnInit() { tsi=iCustom(_Symbol,_Period,"My Files\\TSI\\simpleTSI"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print("TSI System Removed"); } void OnTick() { double tsiVal[]; CopyBuffer(tsi,0,0,1,tsiVal); int fastMA =iMA(_Symbol,_Period,inpFastMAPeriod,0,inpMAType,inpPriceType); int slowMA =iMA(_Symbol,_Period,inpSlowMAPeriod,0,inpMAType,inpPriceType); ArraySetAsSeries(fastMAarray,true); ArraySetAsSeries(slowMAarray,true); CopyBuffer(fastMA,0,0,3,fastMAarray); CopyBuffer(slowMA,0,0,3,slowMAarray); if(fastMAarray[1]<slowMAarray[1]&&fastMAarray[0]>slowMAarray[0]) { if(tsiVal[0]>0) { Comment("Buy Signal", "\nTSI Value ",DoubleToString(tsiVal[0],_Digits), "\nfastMA ",DoubleToString(fastMAarray[0],_Digits), "\nslowMA ",DoubleToString(slowMAarray[0],_Digits)); } } if(fastMAarray[1]>slowMAarray[1]&&fastMAarray[0]<slowMAarray[0]&&tsiVal[0]<0) { if(tsiVal[0]<0) { Comment("Sell Signal", "\nTSI Value ",DoubleToString(tsiVal[0],_Digits), "\nfastMA ",DoubleToString(fastMAarray[0],_Digits), "\nslowMA ",DoubleToString(slowMAarray[0],_Digits)); } } }
Cuáles son las diferencias en este código:
Crearemos cuatro parámetros de entrada de usuario para el tipo de media móvil, el tipo de precio aplicado, el periodo de MA rápida y el periodo de MA lenta y les asignaremos valores por defecto.
input ENUM_MA_METHOD inpMAType = MODE_SMA; //Moving Average Type input ENUM_APPLIED_PRICE inpPriceType = PRICE_CLOSE; //Price type input int inpFastMAPeriod = 10; // Fast moving average period input int inpSlowMAPeriod = 20; //Slow moving average period
Creando dos arrays para el array de la MA rápida y la MA lenta.
double fastMAarray[], slowMAarray[];
Definición de dos medias móviles utilizando una función iMA predefinida para retornar un identificador de media móvil y sus parámetros:
- symbol — símbolo para los cálculos; _Symbol indica el símbolo del gráfico actual.
- period — periodo para los cálculos, _Period indica el marco temporal actual.
- ma_period — parámetros de entrada para las medias móviles rápidas y lentas.
- ma_shift — especificaremos (0), ya que no se requiere ningún desplazamiento.
- ma_method — tipo de MA.
- applied _price — tipo de precio.
int fastMA =iMA(_Symbol,_Period,inpFastMAPeriod,0,inpMAType,inpPriceType); int slowMA =iMA(_Symbol,_Period,inpSlowMAPeriod,0,inpMAType,inpPriceType);
Configuración del indicador AS_SERIES utilizando la función ArraySetAsSeries para MA lentas y rápidas
ArraySetAsSeries(fastMAarray,true); ArraySetAsSeries(slowMAarray,true);
Recuperando los datos de un búfer de dos medias móviles utilizando la función CopyBuffer
CopyBuffer(fastMA,0,0,3,fastMAarray); CopyBuffer(slowMA,0,0,3,slowMAarray);
Vamos a determinar las condiciones de la estrategia,
Si hay una señal de compra:
Si la MA rápida anterior (fastMA) es menor que la MA lenta anterior (slowMA), y la MA rápida actual es mayor que la MA lenta actual, y el tsiVal actual es superior a cero, entonces necesitaremos que el asesor retorne una señal de una compra como comentario en el gráfico en el siguiente orden:
- Señal de compra
- Valor de TSI
- Valor de MA rápida
- Valor de MA lenta
if(fastMAarray[1]<slowMAarray[1]&&fastMAarray[0]>slowMAarray[0]) { if(tsiVal[0]>0) { Comment("Buy Signal", "\nTSI Value ",DoubleToString(tsiVal[0],_Digits), "\nfastMA ",DoubleToString(fastMAarray[0],_Digits), "\nslowMA ",DoubleToString(slowMAarray[0],_Digits)); } }
Si hay una señal de venta:
Si la MA rápida anterior es mayor que la MA lenta anterior, y la MA rápida actual es menor que la MA lenta actual, y el tsiVal actual es inferior a cero, entonces necesitaremos que el asesor retorne una señal de venta como comentario en el gráfico en el siguiente orden:
- Señal de venta
- Valor de TSI
- Valor de MA rápida
- Valor de MA lenta
if(fastMAarray[1]>slowMAarray[1]&&fastMAarray[0]<slowMAarray[0]&&tsiVal[0]<0) { if(tsiVal[0]<0) { Comment("Sell Signal", "\nTSI Value ",DoubleToString(tsiVal[0],_Digits), "\nfastMA ",DoubleToString(fastMAarray[0],_Digits), "\nslowMA ",DoubleToString(slowMAarray[0],_Digits)); } }
Después de compilar este código sin errores y arrastrarlo al gráfico, se abrirá la ventana de datos de entrada:
Como podemos ver, tenemos cuatro parámetros de entrada: tipo de MA, tipo de precio, periodo de MA rápida y periodo de MA lenta. Tras configurar nuestras preferencias y clicar en OK, el asesor se iniciará en el gráfico y sus señales serán las siguientes:
Si hay una señal de compra
Como podemos ver en el gráfico anterior, tenemos una señal de compra en forma de comentario en la esquina superior izquierda según las condiciones de nuestra estrategia, como se muestra a continuación:
- Señal de compra
- Valor de TSI
- Valor de MA rápida
- Valor de MA lenta
Si hay una señal de venta:
Como podemos ver en el gráfico anterior, tenemos una señal de venta en forma de comentario en la esquina superior izquierda según las condiciones de nuestra estrategia, como se muestra a continuación:
- Señal de venta
- Valor de TSI
- Valor de MA rápida
- Valor de MA lenta
Conclusión
En este artículo, hemos aprendido cómo crear nuestro propio indicador técnico True Strength Index según nuestras configuraciones y preferencias específicas. Hemos visto qué información y conocimientos ofrece este indicador que puedan resultarnos muy útiles en el comercio. También hemos aprendido cómo se puede utilizar este indicador personalizado en un sistema comercial simple para generar el valor actual del indicador TSI como comentario en el gráfico. Asimismo, hemos visto cómo utilizar el indicador en un sistema comercial automatizado mediante la creación de un asesor que utiliza los datos de TSI en combinación con otra herramienta técnica, que en nuestro caso, la media móvil. Esta combinación de un TSI personalizado y dos medias móviles genera señales de compra y venta basadas en una estrategia específica que hemos abarcado con detalle en la sección del asesor del sistema TSI.
Espero que este artículo le resulte útil para aprender más sobre trading y programación. Si desea leer otros artículos sobre indicadores y aprender cómo crear sistemas comerciales basados en los indicadores técnicos más populares, puede leer mis artículos anteriores, en los que hablo sobre indicadores populares como la media móvil, las bandas de Bollinger, RSI, MACD, Stochastic y Parabolic SAR, ATR y otros.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/12570
- 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