English Русский 中文 Español Deutsch 日本語
preview
Como criar um indicador personalizado True Strength Index usando MQL5

Como criar um indicador personalizado True Strength Index usando MQL5

MetaTrader 5Negociação | 26 setembro 2023, 15:16
363 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introdução

Indicadores técnicos podem ser muito úteis se os usarmos corretamente, pois podem fornecer informações adicionais que são difíceis de detectar apenas olhando para a ação do preço. Existem muitos indicadores técnicos prontos que podemos usar, mas às vezes podemos achar que precisamos personalizá-los para indicar ou nos fornecer informações específicas, ou precisamos criar um novo com base em nossas ideias vencedoras. Existe uma maneira de criar esses indicadores personalizados no MQL5 e usá-los na plataforma de negociação MetaTrader 5. Neste artigo, vou compartilhar como você pode criar o Indicador True Strength Index do zero. Vamos aprender os detalhes deste indicador e ver como calculá-lo em nosso código. Não apenas isso, mas também aprenderemos como podemos usar este indicador personalizado em um sistema de negociação com base em uma estratégia, criando um Expert Advisor. Vamos abordar tudo isso nos tópicos a seguir:

Depois de dominar os tópicos mencionados, poderemos usar e interpretar o indicador True Strength Index, bem como calculá-lo e codificá-lo como um indicador personalizado em MQL5 para uso no MetaTrader 5. Você também será capaz de implementar o indicador em outros sistemas de negociação ou EAs. Se você deseja desenvolver suas habilidades de programação, aconselho a tentar codificar o conteúdo aqui por conta própria, pois essa prática é um passo muito importante em qualquer processo de aprendizado. Usaremos o MetaTrader 5 para escrever nosso código MQL5 em sua IDE, que está integrada ao terminal de negociação MetaTrader 5. Se você não possui a plataforma ou não sabe como baixá-la e usá-la, pode ler o tópico 'Como escrever código MQL5 no MetaEditor' em meus artigos anteriores.

Atenção! Todo o conteúdo deste artigo é apresentado "tal qual como está", apenas para fins educacionais e não constitui uma recomendação de trading. O artigo não fornece qualquer garantia de resultados. Tudo o que você colocar em prática com base neste artigo, você faz exclusivamente por sua conta e risco, o autor não garante nenhum resultado.


Definindo o True Strength Index (TSI)

Nesta seção, analisaremos o indicador técnico True Strength Index (TSI). Ele foi desenvolvido por William Blau como um indicador técnico que mede o momentum da ação do preço, ou seja, mede a força do instrumento, se é forte ou fraco. Ele oscila em torno da linha zero, sendo assim um indicador oscilador de momentum. Uma linha de sinal pode ser usada com ele para obter sinais adicionais de compra ou venda com base no cruzamento dessas linhas. No entanto, podemos obter sinais com base apenas na linha TSI, com base em seu cruzamento com o nível zero. Se estiver acima da linha zero, significa um momentum de alta, e se estiver abaixo de zero, significa um momentum de baixa. O indicador pode ser usado para detectar áreas de sobrecompra e sobrevenda, bem como divergências de alta e de baixa. Como sabemos que precisamos confirmar seus sinais para aumentar o peso das evidências, é melhor usá-lo acompanhado de outras ferramentas técnicas, que devemos usar no mesmo contexto da ação do preço para obter melhores insights.

Agora, vamos ver como calcular este indicador. O cálculo é realizado em várias etapas, que são:

Cálculo do momentum duplamente suavizado:

  • Cálculo do momentum (mudança de preço) subtraindo o preço anterior do preço atual
  • Cálculo da primeira suavização obtendo a EMA de 25 períodos do momentum calculado
  • Cálculo da segunda suavização obtendo a EMA de 13 períodos da primeira suavização (EMA de 25 períodos do momentum calculado)

Cálculo do momentum absoluto duplamente suavizado:

  • Cálculo do momentum absoluto subtraindo o preço anterior absoluto do preço atual absoluto
  • Cálculo da primeira suavização obtendo a EMA de 25 períodos do momentum absoluto calculado
  • Cálculo da segunda suavização obtendo a EMA de 13 períodos da primeira suavização (EMA de 25 períodos do momentum absoluto calculado)

Calcular TSI = 100 * (Momentum duplamente suavizado / Momentum absoluto duplamente suavizado)

Este cálculo resultará em uma linha oscilante ao redor de zero, medindo o momentum da ação do preço e detectando áreas de sobrecompra e sobrevenda, como mencionamos e outras.


Indicador personalizado TSI Simple

A linguagem de programação MQL5 possui muitos indicadores técnicos predefinidos, e podemos usá-los em nossos sistemas usando uma função predefinida. á falamos sobre muitos desses indicadores em artigos anteriores desta série, discutindo como podemos projetar um sistema de negociação com base nesses indicadores técnicos populares. Você pode examinar os artigos anteriores e talvez encontrar algo útil. A pergunta agora é como podemos criar um indicador se ele não existir no pacote padrão da plataforma ou mesmo se existir, como podemos criar um indicador personalizado para obter os sinais ou triggers desejados. A resposta curta é criar um indicador personalizado usando a linguagem de programação principal, e é isso que faremos nesta parte.

Vamos aprender como criar nosso indicador personalizado True Strength Index usando MQL5. Em seguida, usaremos suas características em outros sistemas ou EAs. As seguintes etapas são para a criação deste indicador personalizado.

Criamos parâmetros adicionais usando #property e ao lado dele especificaremos o valor do identificador e os seguintes são esses parâmetros que precisamos especificar:

  • (indicator_separate_window) — exibição do indicador em uma janela separada.
  • (indicator_buffers) — número de buffers de indicador, especificamos (8).
  • (indicator_plots) — exibição do número de séries gráficas do indicador, especificamos (1).
  • (indicator_label1) — definição do rótulo do número da série gráfica, especificamos (TSI).
  • (indicator_type1) — definição do tipo de construção gráfica indicando um dos valores ENUM_DRAW_TYPE, especificamos (DRAW_LINE).
  • (indicator_color1) — definição da cor da linha do indicador exibida, especificamos (clrBlue).
  • (indicator_style1) — definição do estilo da linha do indicador, especificamos (STYLE_SOLID).
  • (indicator_width1) — definição da espessura da linha do indicador, especificamos (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

Precisamos incluir o arquivo MovingAverage.mqh para usar seu componente em nosso cálculo, e este arquivo está presente no arquivo Include, usando o comando #include. Verifique se os nomes dos arquivos correspondem.

#include <MovingAverages.mqh>

Precisamos definir dois valores de períodos de suavização que usaremos no cálculo do indicador, usando a classe de entrada para que o usuário possa inserir esses valores, caso ele queira atualizar os valores padrão especificados no programa. Após isso, determinaremos o tipo de dados das variáveis (InpSmPeriod1, InpSmPeriod2) que precisamos declarar, usando uint, que é um número inteiro não assinado. Em seguida, atribuiremos (25) a InpSmPeriod1 e (13) a InpSmPeriod2 como valores padrão. 

input uint     InpSmPeriod1   =  25;    // Smoothing period 1
input uint     InpSmPeriod2   =  13;   // Smoothing period 2

Criamos duas variáveis inteiras para os períodos de suavização (smperiod1, smperiod2).

int            smperiod1;
int            smperiod2;

Criamos sete arrays para os buffers do indicador.

double         indBuff[];
double         momBuff[];
double         momSmBuff1[];
double         momSmBuff2[];
double         absMomBuff[];
double         absMomSmBuff1[];
double         absMomSmBuff2[];

Dentro da função OnInit (), realizaremos as seguintes etapas:

Declaramos variáveis (smperiod1, smperiod2) retornando o valor 2 se os parâmetros de entrada do usuário de InpSmPeriod1 e InpSmPeriod2 forem menores que 2, ou retornamos os valores de InpSmPeriod1 e InpSmPeriod2 se houver algo diferente.

   smperiod1=int(InpSmPeriod1<2 ? 2 : InpSmPeriod1);
   smperiod2=int(InpSmPeriod2<2 ? 2 : InpSmPeriod2);

Vinculamos os buffers do indicador com os arrays usando a função (SetIndexBuffer). Seus parâmetros são:

index: define o número do buffer do indicador e os números começam com 0 a 7 em nosso programa.

buffer[]: especifica o array declarado no indicador personalizado.

data_type: especifica o tipo de dados armazenado no array do indicador.

   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);

Configuramos o valor da propriedade do indicador correspondente. Essa propriedade do indicador (valor prop) deve ser do tipo string, mediante a função (IndicatorSetString) com a variante de chamada especificando apenas o identificador da propriedade. Essa etapa é para definir um nome curto para o indicador e determinar os períodos a serem exibidos na parte superior esquerda da janela do indicador. Seus parâmetros são:

  • prop_id: identificador da propriedade do indicador incluída na enumeração (ENUM_CUSTOMIND_PROPERTY_STRING). Em nosso programa, isso será (INDICATOR_SHORTNAME).
  • prop_value: valor da propriedade, que será uma string. No nosso caso, é "True Strength Index ("+(string)smperiod1+", "+(string)smperiod2+")"".
IndicatorSetString(INDICATOR_SHORTNAME,"True Strength Index ("+(string)smperiod1+","+(string)smperiod2+")");

Configuramos outro valor da propriedade do indicador como inteiro para normalizar o valor do indicador de acordo com as casas decimais, mediante a função (IndicatorSetInteger) com a variante de chamada especificando apenas o identificador da propriedade. Seus parâmetros são: 

  • prop_id: identificador da propriedade do indicador incluída na enumeração (ENUM_CUSTOMIND_PROPERTY_INTEGER). Em nosso programa, isso será (INDICATOR_DIGITS).
  • prop_value: valor da propriedade, que será um inteiro. Neste caso, é Digits().
IndicatorSetInteger(INDICATOR_DIGITS,Digits());

Configuramos a flag AS_SERIES para o array, usando a função (ArraySetAsSeries).

   ArraySetAsSeries(indBuff,true);
   ArraySetAsSeries(momBuff,true);
   ArraySetAsSeries(momSmBuff1,true);
   ArraySetAsSeries(momSmBuff2,true);
   ArraySetAsSeries(absMomBuff,true);
   ArraySetAsSeries(absMomSmBuff1,true);
   ArraySetAsSeries(absMomSmBuff2,true);

Após a função OnCalculate,

  • Definimos a flag AS_SERIES para o array fechado de OnCalculate e, em seguida, verificamos se rates_total é menor que 2 para retornar 0.
  • Criamos uma variável inteira (limit) igual a (rates_total-prev_calculated).
  • Verificamos se a variável limit é maior que 1. Nesse caso, precisamos executar as seguintes etapas:
  • Atualizamos a variável limit com o resultado (rates_total - 2).
  • Inicializamos os arrays numéricos do tipo double com o valor fornecido usando a função (ArrayInitialize). Seus parâmetros são array[] para especificar o array numérico a ser inicializado e outro parâmetro é value para especificar o novo valor a ser definido.
   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);
     }

Criamos um laço para atualizar o momBuff[i], absMomBuff[i]. As novas funções usadas nesta etapa são:

  • operação de laço (for) com três expressões e uma instrução executável.
  • IsStopped() permite verificar se ocorreu um encerramento forçado do programa mql5.
  • MathAbs que retorna um valor absoluto (módulo), e podemos usar febs() para obter o mesmo resultado.
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      momBuff[i]=close[i]-close[i+1];
      absMomBuff[i]=MathAbs(momBuff[i]);
     }

Verificamos o seguinte usando a função ExponentialMAOnBuffer do arquivo Include (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;

Criamos outro laço para atualizar a variável indBuff[i] usando a função for.

   for(int i=limit; i>=0 && !IsStopped(); i--)
      indBuff[i]=(absMomSmBuff2[i]!=0 ? 100.0*momSmBuff2[i]/absMomSmBuff2[i] : 0);

No final do programa, temos a função return (rates_total).

   return(rates_total);

Desse modo, agora concluímos o código para criar nosso indicador personalizado TSI, e você também pode editar suas preferências em seu código para obter mais personalizações. O código completo do indicador tem a seguinte aparência:

//+------------------------------------------------------------------+
//|                                                   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);
  }

Após compilar este código sem erros, encontraremos o indicador entre os disponíveis na pasta de Indicadores em seu navegador, arrastando-o e soltando-o no gráfico desejado. Encontraremos a janela do indicador e as seguintes entradas:

simpleTSI inputs win

Assim, temos duas entradas que o usuário pode determinar, e os valores padrão são 25 para o período de suavização 1 e 13 para o período de suavização 2. No entanto, o usuário ainda pode editá-los conforme suas preferências, como mencionamos.

 simpleTSI colors win

Podemos ver na imagem anterior na guia de cores que o usuário pode escolher a cor, largura e estilo da linha TSI. Após determinar nossas preferências de entrada e o estilo do indicador, como mencionamos, podemos encontrar o indicador no gráfico, igual ao seguinte:

 simpleTSI attached

Como podemos ver no gráfico anterior, temos a linha do indicador TSI em uma janela separada abaixo dos preços, e essa linha oscila em torno de zero. E temos o rótulo do indicador, seus períodos de suavização e o valor do indicador.


Um EA personalizado do TSI

Nesta parte, aprenderemos de maneira muito simples como usar nosso indicador personalizado em um sistema automatizado para que ele possa gerar um sinal ou ação específica quando uma condição específica for acionada. Começaremos por um sistema muito simples, criando um Expert Advisor, que gerará um comentário no gráfico com o valor atual do TSI, antes de desenvolver um EA que execute instruções mais complexas.

Bem, abaixo estão as etapas necessárias para criar nosso Expert Advisor:

  • Criação de uma variável inteira (TSI).
  • Definição do TSI usando a função iCustom para retornar o descritor do indicador e seus parâmetros:
    • symbol — nome do símbolo; no nosso caso, é _Symbol, ou seja, calculamos o indicador pelo símbolo do gráfico atual.
    • period — período gráfico para cálculo; o valor _period significa que o indicador será calculado no período gráfico atual.
    • name — caminho para o indicador personalizado.
  • Exibição do texto "TSI System Removed" em OnDeinit(const int reason) após a remoção de um EA.
  • Criação do array tsiVal[]
  • Obtenção dos dados do buffer do indicador TSI usando a função CopyBuffer com a variante de chamada pela primeira posição e o número de elementos necessários. Seus parâmetros são:
    • indicator_handle — identificador do indicador que usaremos (TSI).
    • buffer_num — número do buffer de indicador, definimos (0).
    • start_pos — posição inicial para cópia, especificamos (0).
    • count — número de dados para cópia, especificamos (1).
    • buffer[]: array para cópia, especificamos (tsiVal).
  • Uso da função Comment para mostrar o valor atual do TSI convertido em uma string, mediante a função (DoubleToString) com os parâmetros value para especificar o valor atual do TSI e as casas decimais para especificar o número de dígitos, usaremos (_Digits) para o valor atual.

O código completo será o mesmo que o seguinte:

//+------------------------------------------------------------------+
//|                                           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));
  }

Após compilar este código sem erros e executá-lo, ele será anexado ao gráfico. O seguinte é um exemplo de seu sinal com base nessa estratégia:

 Sinal do Expert Advisor iCustom TSI

Como podemos ver, temos um comentário no canto superior esquerdo do gráfico com o valor atual do TSI. Se quisermos ter certeza de que o sinal é o mesmo que temos com base no indicador, podemos anexar o EA e inserir o indicador ao mesmo tempo para verificar os valores. O seguinte é para garantir nosso trabalho:

Expert Advisor iCustom TSI iniciado - o sinal é o mesmo

Como podemos ver no canto superior direito, temos o EA anexado e seu sinal aparece no canto superior esquerdo com o valor atual do TSI ao mesmo tempo em que temos o indicador TSI inserido no gráfico como uma janela separada abaixo dos preços e seu valor acima. Sua linha no canto esquerdo coincide com o sinal do EA.


Um EA do TSI System

Nesta parte, desenvolveremos um EA com base no indicador TSI personalizado criado para obter sinais com base em uma estratégia específica. Por favor, observe que a estratégia que vamos discutir destina-se apenas a fins educacionais. Ela precisará de otimizações, assim como qualquer outra estratégia. Portanto, é necessário testá-la antes de usá-la em uma conta real para garantir que seja útil para você.

Usaremos o indicador TSI personalizado combinado com duas médias móveis para obter sinais de compra e venda com base em uma estratégia específica, conforme a seguir:

Usaremos duas médias móveis simples, uma rápida com um período de 10 e a outra lenta com um período de 20, além do nosso indicador TSI personalizado. Se o valor anterior da média móvel rápida for menor que o valor anterior da média móvel lenta e, ao mesmo tempo, a média móvel rápida atual for maior que a média móvel lenta atual, isso significa que temos uma cruzamento de média móvel de alta, então verificaremos se o valor atual do TSI é maior que zero para obter um sinal de compra como um comentário no gráfico. Se o valor anterior da média móvel rápida for maior que o valor anterior da média móvel lenta e, ao mesmo tempo, a média móvel rápida atual for menor que a média móvel lenta atual, isso significa que temos uma cruzamento de média móvel de baixa, então verificaremos se o valor atual do TSI é menor que zero para obter um sinal de venda como um comentário no gráfico.

Simplesmente:

Caso fastMA[1]<slowMA[1] && fastMA[0]>slowMA[0] && tsiVal[0]>0 ==> Sinal de compra
Caso fastMA[1]>slowMA[1] && fastMA[0]<slowMA[0] && tsiVal[0]<0 ==> Sinal de venda

O seguinte é o código completo para criar esse tipo de sistema:

//+------------------------------------------------------------------+
//|                                                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));
        }
     }
  }

As diferenças neste código são as seguintes:

Criamos quatro entradas pelo usuário para o tipo de média móvel, o tipo de preço aplicado, o período da MA rápida e o período da MA lenta, e atribuir valores padrão para eles.

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

Criamos dois arrays para a MA rápida e a MA lenta.

double fastMAarray[], slowMAarray[];

Definimos as duas médias móveis usando a função iMA predefinida para retornar o identificador da média móvel, e seus parâmetros são:

  • symbol — símbolo para cálculos; _Symbol é o símbolo do gráfico atual.
  • period — período para cálculos, _Period é o período gráfico atual.
  • ma_period — parâmetros de entrada para médias móveis rápidas e lentas.
  • ma_shift — especificamos (0), pois não é necessário nenhum deslocamento.
  • ma_method — tipo de MA.
  • applied _price — tipo de preço.
   int fastMA =iMA(_Symbol,_Period,inpFastMAPeriod,0,inpMAType,inpPriceType);
   int slowMA =iMA(_Symbol,_Period,inpSlowMAPeriod,0,inpMAType,inpPriceType);

Configuramos a flag AS_SERIES usando a função ArraySetAsSeries para as médias móveis lenta e rápida.

   ArraySetAsSeries(fastMAarray,true);
   ArraySetAsSeries(slowMAarray,true);

Obtemos dados do buffer das duas médias móveis usando a função CopyBuffer.

   CopyBuffer(fastMA,0,0,3,fastMAarray);
   CopyBuffer(slowMA,0,0,3,slowMAarray);

Definimos as condições da estratégia:

No caso de sinal de compra:

Se a média móvel rápida anterior for menor que a média móvel lenta anterior e a média móvel rápida atual for maior que a média móvel lenta atual e ao mesmo tempo o valor atual do TSI for maior que zero, precisamos que o EA retorne o sinal de compra como um comentário no gráfico na seguinte ordem:

  • Sinal de compra
  • Valor do TSI
  • Valor da MA rápida
  • Valor da 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));
        }
     }

No caso de sinal de venda:

Se a média móvel rápida anterior for maior que a média móvel lenta anterior e a média móvel rápida atual for menor que a média móvel lenta atual e ao mesmo tempo o valor atual do TSI for menor que zero, precisamos que o EA retorne o sinal de venda como um comentário no gráfico na seguinte ordem:

  • Sinal de venda
  • Valor do TSI
  • Valor da MA rápida
  • Valor da 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));
        }
     }

Depois de compilar esse código sem erros e arrastá-lo para o gráfico, será aberta a janela de dados de entrada:

Parâmetros de entrada do Expert Advisor TSI System

Como podemos ver, temos quatro parâmetros de entrada para o tipo de MA, tipo de preço, período da MA rápida e período da MA lenta. Depois de configurar nossas preferências e pressionar OK, podemos ver que o EA está anexado ao gráfico, e seus sinais serão iguais aos seguintes:

No caso de sinal de compra

 Expert Advisor TSI System - sinal de compra

Como podemos ver no gráfico anterior, temos um sinal de compra como um comentário no canto superior esquerdo, de acordo com nossas condições de estratégia, como mencionado anteriormente.

  • Sinal de compra
  • Valor do TSI
  • Valor da MA rápida
  • Valor da MA lenta

No caso de sinal de venda:

 Expert Advisor TSI System - sinal de venda

Como podemos ver no gráfico anterior, temos um sinal de venda como um comentário no canto superior esquerdo, de acordo com nossas condições de estratégia, como mostrado abaixo:

  • Sinal de venda
  • Valor do TSI
  • Valor da MA rápida
  • Valor da MA lenta

Considerações finais

Neste artigo, aprendemos como criar seu próprio indicador técnico True Strength Index para implementar suas configurações e preferências específicas. Vimos quais informações e insights este indicador fornece, o que pode ser muito útil na negociação. Também aprendemos como usar este indicador personalizado em um sistema de negociação simples para gerar o valor atual do indicador TSI como um comentário no gráfico. Também vimos como usar o indicador em um sistema de negociação automatizado, criando o EA que utiliza os dados do TSI combinados com outra ferramenta técnica, que, no nosso caso, é a média móvel. Essa combinação do TSI personalizado e duas médias móveis gerou sinais de compra e venda com base em uma estratégia específica, que detalhamos no tópico do EA do Sistema TSI.

Espero que este artigo seja útil para sua aprendizagem de negociação e programação. Se você quiser ler outros artigos sobre indicadores e aprender como criar sistemas de negociação com base nos indicadores técnicos mais populares, consulte meus artigos anteriores, nos quais cobri indicadores populares, como a média móvel, Bandas de Bollinger, RSI, MACD, Estocástico, Parabolic SAR, ATR e outros.

Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/12570

Arquivos anexados |
simpleTSI.mq5 (7.46 KB)
iCustomTSI_ea.mq5 (0.81 KB)
TSI_System_EA.mq5 (2.09 KB)
Desenvolvendo um sistema de Replay (Parte 28): Projeto Expert Advisor — Classe C_Mouse (II) Desenvolvendo um sistema de Replay (Parte 28): Projeto Expert Advisor — Classe C_Mouse (II)
Quanto de fato os primeiros sistema capazes de fatorar alguma coisa, começaram a ser produzidos. Tudo tinha que ser feito por engenheiros com grande conhecimento, no que estava sendo projetado. Isto nos primórdios da computação, onde se quer existia algum tipo de terminal, para que fosse possível programar algo. Conforme ia se desenvolvendo, e o interesse de que mais pessoas também conseguisse criar algo, começou surgir novas ideias e meios, de programar aquelas máquinas, que antes era feito mudando a posição dos conectores. Assim começamos a ter os primeiros terminais.
Desenvolvendo um sistema de Replay (Parte 27): Projeto Expert Advisor — Classe C_Mouse (I) Desenvolvendo um sistema de Replay (Parte 27): Projeto Expert Advisor — Classe C_Mouse (I)
Neste artigo irá nascer a classe C_Mouse. Esta foi pensada de maneira que a programação, seja feita no mais alto nível quanto for possível ser feita. Mas dizer que trabalharemos em alto, ou baixo nível, nada tem haver com questões de colocarmos palavrões ou chavões no meio do código. Longe disto. Trabalhar em alto nível ou de baixo nível, quando se fala em programação, diz o quanto o programa pode ser mais simples ou mais difícil de ser lido por outro programador.
Domine e utilize o testador de estratégias MQL5 de forma eficiente Domine e utilize o testador de estratégias MQL5 de forma eficiente
Os desenvolvedores MQL5 devem dominar diversas ferramentas essenciais. Entre elas, destaca-se o testador de estratégias. Este artigo serve como um guia prático para a utilização do testador de estratégias MQL5.
Integrando modelos de ML ao Testador de Estratégias (Conclusão): Implementação de um Modelo de Regressão para Previsão de Preço Integrando modelos de ML ao Testador de Estratégias (Conclusão): Implementação de um Modelo de Regressão para Previsão de Preço
Este artigo descreve a implementação de um modelo de regressão de árvores de decisão para prever preços de ativos financeiros. Foram realizadas etapas de preparação dos dados, treinamento e avaliação do modelo, com ajustes e otimizações. No entanto, é importante destacar que o modelo é apenas um estudo e não deve ser usado em negociações reais.