![O exemplo simples da criação de um indicador utilizando a lógica Fuzzy](https://c.mql5.com/i/articles/overlay.png)
O exemplo simples da criação de um indicador utilizando a lógica Fuzzy
Introdução
O uso de vários métodos para análise de mercados financeiros torna-se cada vez mais popular entre os negociantes nos anos recentes. Gostaria de dar minha contribuição e mostrar como fazer um bom indicador escrevendo uma dúzia de linhas de código. Além disso, revelarei de forma breve o básico sobre a lógica Fuzzy.
Qualquer pessoa interessada neste assunto e que queira explorá-lo mais profundamente poderá ler os seguintes trabalhos:
2. Bocharnikov V."Fuzzy Technology: Mathematical Background. Simulation Practice in Economics" (Tecnologia Fuzzy: Background matemático. Prática de simulação em economia) (em Russo).
3. S.N. Sivanandam, S. Sumathi, S.N. Deepa. Introduction to Fuzzy Logic using MATLAB. (Introdução à lógica Fuzzy utilizando o MATLAB.
4. C. Kahraman. Fuzzy Engineering Economics with Applications (Studies in Fuzziness and Soft Computing). (Economia de engenharia Fuzzy com aplicações (Estudos sobre Imprecisão e Soft Computing)).
1. Básico sobre a lógica Fuzzy
Como podemos explicar aos nossos computadores os significados de expressões tão simples como "...um pouco mais...", "...muito rápido...", "...quase nada..."? Na realidade, é bastante possível utilizar os elementos da teoria de conjuntos fuzzy, ou melhor, as chamadas "funções de pertinência". Eis um exemplo do livro de A. Leonenkov:
Vamos descrever a função de pertinência para a frase "café quente": a temperatura do café deve ser considerada estar em uma faixa de 0 a 100 graus Celsius pelo simples motivo de que temperaturas abaixo de 0 graus o congelaria, enquanto temperaturas acima de 100 graus o faria evaporar. é bastante óbvio que uma xícara de café com uma temperatura de 20 graus não pode ser considerada quente, ou seja, a função de pertinência na categoria "quente" é igual a 0, enquanto uma xícara de café com uma temperatura de 70 graus definitivamente pertence à categoria "quente" e, consequentemente, o valor da função é igual a 1 neste caso.
Para os valores de temperatura que estão entre estes dois valores extremos, a situação não é tão definida. Algumas pessoas podem considerar uma xícara de chá com uma temperatura de 55 graus "quente", enquanto outras podem considerar "não muito quente". Isso é a "imprecisão".
No entanto, podemos imaginar o olhar aproximado da função de pertinência: ele está "monotonamente aumentando":
A figura acima mostra a função de pertinência "linear por partes".
Assim, a função pode ser definida pela seguinte expressão analítica:
Usaremos tais funções para nosso indicador.
2. Função de pertinência
De uma forma ou de outra, a tarefa de qualquer indicador técnico é determinar o estado atual do mercado (tendência crescente, decrescente, plana), bem como a geração de sinais de entrada e saída do mercado. Como isso pode ser feito com a ajuda das funções de pertinência? é bem fácil.
Primeiro de tudo, precisamos definir as condições limite. Teremos as seguintes condições limite: para «tendência 100% crescente» o limite será o cruzamento do EMA tendo um período 2, com base no preço típico (H+L+C)/3 com o limite superior Envelopes tendo os parâmetros 8, 0.08, SMA, Fechar, enquanto para a «tendência 100% decrescente» ele será o cruzamento do mesmo EMA com o limite inferior Envelopes. Tudo que estiver colocado entre estas duas condições será assumido como plano. Vamos acrescentar mais um envelope tendo os parâmetros 32, 0.15, SMA, Fechar.
Como resultado, teremos duas funções de pertinência idênticas. O sinal de compra será ativado quando ambas funções forem iguais a 1, enquanto o sinal de venda será ativado quando ambas funções forem iguais a -1, respectivamente. Devido a ser conveniente construir gráficos com uma faixa de -1 a 1, o gráfico resultante será obtido como a média aritmética de duas funções F(x)= (f1(x)+f2(x))/2.
é assim que fica no gráfico:
Neste caso, a função de pertinência terá a seguinte representação gráfica:
Analiticamente, ela pode ser escrita da seguinte forma:
,
onde a e b são as linhas envelope superiores e inferiores, respectivamente, enquanto x é um valor de EMA(2).
Com a função definida, podemos agora prosseguir com a escrita do código do indicador.
3. Criando o código do programa
Primeiramente, devemos definir o que e como vamos desenhar.
Os resultados dos cálculos da função de pertinência serão exibidos como a linha - vermelha e azul, respectivamente.
A média aritmética será exibida como o histograma da linha zero e colorida em uma das cinco cores dependendo do valor da função resultante:
O estilo de desenhoDRAW_COLOR_HISTOGRAM será utilizado para isso.
Vamos desenhar retângulos azuis e vermelhos como sinais de comprar e sair nas barras do histograma, os valores destes são iguais a 1 ou -1.
Agora, é hora de executar o MetaEditor e começar. New (Novo)->Custom Indicator (Personalizar indicador)->Next (Próximo)... Preencha o campo "Parâmetros":
Crie os buffers:
Após clicar no botão "Finish" (Terminar), recebemos um código fonte e começamos a melhorá-lo.
Primeiro, vamos definir o número de buffers. Sete deles já foram criados pelo Assistente (5 para dados, 2 para cor). Precisamos de 5 mais.
#property indicator_minimum -1.4 // Setting fractional values #property indicator_maximum 1.4 // Expert Advisors wizard ignores fractional parts for some reason #property indicator_buffers 12 // Changing the value from 7 to 12 (5 more buffers have been added)Vamos editar os parâmetros de entrada:
input string txt1="----------"; input int Period_Fast=8; input ENUM_MA_METHOD Method_Fast = MODE_SMA; /*Smoothing method*/ //moving average smoothing method input ENUM_APPLIED_PRICE Price_Fast = PRICE_CLOSE; input double Dev_Fast=0.08; input string txt2="----------"; input int Period_Slow=32; input ENUM_MA_METHOD Method_Slow = MODE_SMA; input ENUM_APPLIED_PRICE Price_Slow = PRICE_CLOSE; input double Dev_Slow=0.15; /*Deviation parameter*/ input string txt3="----------"; input int Period_Signal=2; input ENUM_MA_METHOD Method_Signal = MODE_EMA; input ENUM_APPLIED_PRICE Price_Signal = PRICE_TYPICAL; input string txt4="----------";
Comentários após a variável declarada são muito úteis. O texto dos comentários é inserido na janela dos parâmetros do indicador.
A possibilidade de criação de listas é também bastante útil:
Reservando as variáveis para os buffers e manipuladores do indicador:
int Envelopes_Fast; // Fast envelope int Envelopes_Slow; // Slow envelope int MA_Signal; // Signal line double Env_Fast_Up[]; // Fast envelope upper border double Env_Fast_Dn[]; // Fast envelope lower border double Env_Slow_Up[]; // Slow envelope upper border double Env_Slow_Dn[]; // Slow envelope lower border double Mov_Sign[]; // Signal line
Agora, vamos para a função OnInit().
Vamos adicionar um pouco de beleza: especifique o nome do indicador e remova os zeros decimais extras:
IndicatorSetInteger(INDICATOR_DIGITS,1); // setting display accuracy, we do not need some outstanding accuracy values string name; // indicator name StringConcatenate(name, "FLE ( ", Period_Fast, " , ", Dev_Fast, " | ", Period_Slow, " , ", Dev_Slow, " | ", Period_Signal, " )"); IndicatorSetString(INDICATOR_SHORTNAME,name);
e adicione os buffers faltantes:
SetIndexBuffer(7,Env_Fast_Up,INDICATOR_CALCULATIONS); SetIndexBuffer(8,Env_Fast_Dn,INDICATOR_CALCULATIONS); SetIndexBuffer(9,Env_Slow_Up,INDICATOR_CALCULATIONS); SetIndexBuffer(10,Env_Slow_Dn,INDICATOR_CALCULATIONS); SetIndexBuffer(11,Mov_Sign,INDICATOR_CALCULATIONS);
A média do parâmetroINDICATOR_CALCULATIONS significa que os dados do buffer são necessários apenas para cálculos intermediários. Isso não será exibido no gráfico.
Observe como os indicadores com os buffers coloridos são declarados:
SetIndexBuffer(4,SignalBuffer1,INDICATOR_DATA); // All indicator buffers at first SetIndexBuffer(5,SignalBuffer2,INDICATOR_DATA); // as this is Color Histogram2, then it has 2 data buffers SetIndexBuffer(6,SignalColors,INDICATOR_COLOR_INDEX);// the color buffer comes next.
Preenchendo os manipuladores:
Envelopes_Fast = iEnvelopes(NULL,0,Period_Fast,0,Method_Fast,Price_Fast,Dev_Fast); Envelopes_Slow = iEnvelopes(NULL,0,Period_Slow,0,Method_Slow,Price_Slow,Dev_Slow); MA_Signal = iMA(NULL,0,Period_Signal,0,Method_Signal,Price_Signal);
Todo trabalho com a função OnInit() terminou.
Agora, vamos criar a função que irá calcular o valor da função de pertinência:
double Fuzzy(double x,double a, double c) { double F; if (a<x) F=1; // 100% uptrend else if (x=c) F=(1-2*(a-x)/(a-c));// Flat else if (x<c) F=-1; // 100% downtrend return (F); }
Os preparativos terminaram. As variáveis e buffers estão declarados, os manipuladores atribuídos.
Agora é hora de prosseguirmos com a função básica OnCalculate().
Primeiro de tudo, vamos escrever os valores dos indicadores necessários nos buffers intermediários. Use a função CopyBuffer() :
CopyBuffer(Envelopes_Fast, // Indicator handle UPPER_LINE, // Indicator buffer 0, // The point to start 0 - from the very beginning rates_total, // How many to be copied - All Env_Fast_Up); // The buffer the values are written in // - the rest are done in a similar way CopyBuffer(Envelopes_Fast,LOWER_LINE,0,rates_total,Env_Fast_Dn); CopyBuffer(Envelopes_Slow,UPPER_LINE,0,rates_total,Env_Slow_Up); CopyBuffer(Envelopes_Slow,LOWER_LINE,0,rates_total,Env_Slow_Dn); CopyBuffer(MA_Signal,0,0,rates_total,Mov_Sign);
Aqui devemos adicionar o código para a otimização dos cálculos (é realizado o recálculo de apenas a última barra):
// declaring start variable for storing the index of the bar, recalculation of the indicator buffers will be // carried out from. int start; if (prev_calculated==0) // in case no bars have been calculated { start = Period_Slow; // not all indicators have been calculated up to this value, therefore, there is no point in executing the code } else start=prev_calculated-1; for (int i=start;i<rates_total;i++) { // All remaining code will be written here }
Não resta muito do código.
Definindo os parâmetros x, a, b, realizando o cálculo do valor da função de pertinência e o escrevendo no buffer adequado:double x = Mov_Sign[i]; // Signal // Setting the first membership function parameters: double a1 = Env_Fast_Up[i]; // Upper border double b1 = Env_Fast_Dn[i]; // setting the first membership function value and writing it to the buffer Rule1Buffer[i] = Fuzzy(x,a1,b1); // Setting the second membership function parameters: double a2 = Env_Slow_Up[i]; // Upper border double b2 = Env_Slow_Dn[i]; // setting the second membership function value and writing it to the buffer Rule2Buffer[i] = Fuzzy(x,a2,b2);
Duas linhas do indicador estão criadas:
Agora, vamos calcular o valor resultante.
ResultBuffer[i] = (Rule1Buffer[i]+Rule2Buffer[i])/2;
Depois, devemos pintar as barras do histograma nas cores apropriadas: como temos cinco cores, então o ResultColor[i] pode ter qualquer valor de 0 a 4.
Geralmente, o número de cores possíveis é 64. Portanto, é uma grande oportunidade para aplicar habilidades e criatividade.
for (int ColorIndex=0;ColorIndex<=4;ColorIndex++) { if (MathAbs(ResultBuffer[i])>0.2*ColorIndex && MathAbs(ResultBuffer[i])<=0.2*(ColorIndex+1)) { ResultColors[i] = ColorIndex; break; } }
Então, devemos desenhar os retângulos de sinal. Usaremos o estilo de desenho DRAW_COLOR_HISTOGRAM2 .
Ele tem dois buffers de dados com uma barra de histograma e um buffer colorido sendo inseridos entre eles.
Os valores dos buffers de dados sempre serão os mesmo: 1.1 e 1.3 para um sinal de compra, -1.1 e -1.3 para um sinal de venda, respectivamente.
EMPTY_VALUE representará a ausência de sinal.
if (ResultBuffer[i]==1) { SignalBuffer1[i]=1.1; SignalBuffer2[i]=1.3; SignalColors[i]=1; } else if (ResultBuffer[i]==-1) { SignalBuffer1[i]=-1.1; SignalBuffer2[i]=-1.3; SignalColors[i]=0; } else { SignalBuffer1[i]=EMPTY_VALUE; SignalBuffer2[i]=EMPTY_VALUE; SignalColors[i]=EMPTY_VALUE; }
Clique em "Compile" (Compilar) e voilà!
Conclusão
O que mais pode ser adicionado? Neste artigo, mencionei a abordagem mais básica da lógica Fuzzy.
Existe espaço suficiente aqui para diversos experimentos. Por exemplo, podemos usar a seguinte função:
Eu acho que não será difícil para você escrever a expressão analítica para isso e descobrir as condições adequadas.
Boa sorte!
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/178
![Crie seu próprio Market Watch usando as classes da biblioteca padrão](https://c.mql5.com/2/0/visual.png)
![Assistente MQL5: criar Expert Advisors sem programação](https://c.mql5.com/2/0/editor_wizard.png)
![Série de preço médio para cálculos intermediários sem utilizar buffers adicionais](https://c.mql5.com/2/0/averages_MQL5__1.png)
![Gás neural em desenvolvimento: Implementação em MQL5](https://c.mql5.com/2/0/neural_gas_MQL5.png)
![MQL5 - Linguagem para estratégias de negociação inseridas no terminal do cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso