Participe de nossa página de fãs
Coloque um link para ele, e permita que outras pessoas também o avaliem
Avalie seu funcionamento no terminal MetaTrader 5
- Visualizações:
- 335
- Avaliação:
- Publicado:
-
Precisa de um robô ou indicador baseado nesse código? Solicite-o no Freelance Ir para Freelance
A configuração
Precisaremos de :
- 1 gráfico em ziguezague
- 2 buffers de dados para os altos e baixos
- parâmetros de entrada
- um conjunto contínuo de variáveis de sistema que são redefinidas sempre que o indicador é recalculado
#property indicator_buffers 2 #property indicator_plots 1 input double retracement=23.6;//valor da retração input double minSizeInAtrUnits=0.0;//tamanho mínimo das ondas em unidades atr input int rollingAtrPeriod=14;//período de rolagem atr input color Color=clrDodgerBlue;//cor da onda input int Width=3;//largura da onda input ENUM_LINE_STYLE Style=STYLE_SOLID;//estilo de onda //+------------------------------------------------------------------+ //| Função de inicialização do indicador personalizado //+------------------------------------------------------------------+ //--- ondas ascendentes e descendentes double upWaves[],dwWaves[];
A matriz upWaves armazenará os máximos e a matriz dwWaves armazenará os mínimos
Variáveis do sistema:
Precisamos saber o tipo da última onda, onde ela começou, onde terminou, a distância em barras do início e do fim.
Em seguida, precisamos de uma variável local de alta e baixa, bem como as distâncias em barras de cada ponto.
//--- mantendo o controle do ziguezague //--- o tipo de onda que temos [0] nenhuma [1] para cima [2] para baixo int wave_type=0; //--- o preço a partir da onda (preço inicial) double wave_start_price=0.0; //--- o preço até a onda (preço final) double wave_end_price=0.0; //--- a distância em barras do preço inicial int wave_start_distance=0; //--- a distância em barras do preço final int wave_end_distance=0; //--- rastreamento de preço alto double high_mem=0.0; int distance_from_high=0; //--- rastreamento de preço baixo double low_mem=0.0; int distance_from_low=0; //--- rolling atr double rollingAtr=0.0; int rollingAtrs=0;
Finalmente, a unidade de atr de rolagem e quantas foram calculadas
Em seguida, criamos uma função de reinicialização do sistema:
void resetSystem(){ ArrayFill(upWaves,0,ArraySize(upWaves),0.0); ArrayFill(dwWaves,0,ArraySize(dwWaves),0.0); wave_type=0; wave_start_price=0.0; wave_end_price=0.0; wave_start_distance=0; wave_end_distance=0; high_mem=0.0; low_mem=0.0; distance_from_high=0; distance_from_low=0; rollingAtr=0.0; rollingAtrs=0; }
Coisas padrão, preencher as matrizes com zeros e redefinir as variáveis do sistema.
Na inicialização, configuramos os buffers, o gráfico e chamamos a função reset pela primeira vez:
SetIndexBuffer(0,upWaves,INDICATOR_DATA); SetIndexBuffer(1,dwWaves,INDICATOR_DATA); PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_ZIGZAG); PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Color); PlotIndexSetInteger(0,PLOT_LINE_WIDTH,Width); PlotIndexSetInteger(0,PLOT_LINE_STYLE,Style); resetSystem();
Então, vamos direto para o cálculo.
A primeira coisa que precisamos resolver é o atr de rolagem.
Até que tenhamos coletado mais barras do que o período do atr, não faremos mais nada.
A parte que gerencia o atr móvel é a seguinte:
- se não tivermos coletado mais do que o período, continuaremos adicionando o intervalo das barras encontradas a um somatório
- quando atingirmos o período, faremos a primeira divisão (média)
- depois disso, cortamos uma parte do rolling atr, que é atr/período, e adicionamos uma nova parte, que é o intervalo de barras/período
//--- gerenciar o atr rollingAtrs++; if(rollingAtrs>rollingAtrPeriod){ double new_portion=((high[i]-low[i])/_Point)/((double)rollingAtrPeriod); //--- removemos uma parte antiga e adicionamos uma nova parte rollingAtr=(rollingAtr)-(rollingAtr/((double)rollingAtrPeriod))+new_portion; } else if(rollingAtrs<=rollingAtrPeriod){ rollingAtr+=(high[i]-low[i])/_Point; if(rollingAtrs==rollingAtrPeriod){ rollingAtr/=((double)rollingAtrs); //--- iniciar a memória para altos e baixos e o sistema high_mem=high[i]; low_mem=low[i]; distance_from_high=0; distance_from_low=0; } }
Incrível, agora há outro problema.
A base desse ziguezague é um retrocesso.
Mas para que ocorra uma retração, deve haver pelo menos uma onda.
Mas qual será o retrocesso da primeira onda? xD
Por esse motivo, faremos o seguinte:
- assim que o atr for preenchido (atr coletado = período), pegaremos a máxima e a mínima em nossas variáveis do sistema
- o lado que conseguir formar uma onda com um tamanho válido em unidades de atr e formar uma nova máxima (onda ascendente) ou uma nova mínima (onda descendente) vence
Dessa forma, não temos uma retração como onda inicial, mas precisamos iniciar a sequência de alguma forma.
Observe que também poderíamos ter optado por uma abordagem fractal clássica aqui apenas para a primeira onda e depois continuar com retrações.
É isso que fazemos enquanto não tivermos uma onda:
//--- se ainda não tivermos um tipo de onda else{ //--- se quebramos a máxima e não a mínima if(high[i]>high_mem&&low[i]>=low_mem){ double new_wave_size_in_atr_units=((high[i]-low_mem)/_Point)/rollingAtr; //--- se o novo tamanho do pacote for válido if(new_wave_size_in_atr_units>=minSizeInAtrUnits){ //--- iniciar uma nova onda ascendente wave_type=1; //--- o preço inicial é o preço mínimo wave_start_price=low_mem; wave_start_distance=distance_from_low; //--- o preço final é a nova máxima wave_end_price=high[i]; wave_end_distance=0; //--- desenhar a onda dwWaves[i-wave_start_distance]=low_mem; upWaves[i]=high[i]; //--- mudar a alta high_mem=high[i]; distance_from_high=0; //--- mudar a baixa low_mem=low[i]; distance_from_low=0; } } //--- se quebramos a mínima e não a máxima else if(low[i]<low_mem&&high[i]<=high_mem){ double new_wave_size_in_atr_units=((high_mem-low[i])/_Point)/rollingAtr; //--- se o novo tamanho do pacote for válido if(new_wave_size_in_atr_units>=minSizeInAtrUnits){ //--- iniciar uma nova onda descendente wave_type=-1; //--- preço inicial é o mem alto wave_start_price=high_mem; wave_start_distance=distance_from_high; //--- o preço final é o novo mínimo wave_end_price=low[i]; wave_end_distance=0; //--- desenhar a onda upWaves[i-wave_start_distance]=high_mem; dwWaves[i]=low[i]; //--- mudar a alta high_mem=high[i]; distance_from_high=0; //--- mudar a baixa low_mem=low[i]; distance_from_low=0; } } //--- se quebrarmos ambos else if(low[i]<low_mem&&high[i]>high_mem){ //--- alterá-los high_mem=high[i]; low_mem=low[i]; distance_from_high=0; distance_from_low=0; } }
Ótimo. Agora, a parte final.
- Se tivermos uma onda ascendente:
- Se houver uma nova alta, mova o ziguezague da posição da alta anterior para a nova posição da alta, o que podemos fazer, pois mantemos as distâncias das barras, e também atualizamos a mínima e a distância da mínima.
- Se uma nova mínima for registrada ou se uma nova mínima for estabelecida, calcularemos a distância do pico até a mínima e a dividiremos pelo tamanho da onda. Assim, se o tamanho da onda for de 100 pontos e a retração for de 24 pontos, obteremos 24/100 0,24 e, em seguida, x 100 24%. Se o tamanho da nova onda "seria" que retrai a anterior também for válido em relação às unidades atr, iniciaremos uma nova onda descendente, definiremos os novos máximos e mínimos locais e as distâncias das barras.
Aqui está o código relevante para o que foi dito acima:
//--- se tivermos uma onda ascendente if(wave_type==1){ //--- se a onda se expandir para cima if(high[i]>wave_end_price){ //--- remover o preço final anterior de sua posição na matriz (0,0=vazio) upWaves[i-wave_end_distance]=0.0; //--- coloque-o na nova posição upWaves[i]=high[i]; wave_end_price=high[i]; wave_end_distance=0; //--- mudar a alta high_mem=high[i]; distance_from_high=0; //--- mudar a baixa low_mem=low[i]; distance_from_low=0; } //--- verificar a retração if(low[i]<low_mem||distance_from_low==0){ low_mem=low[i]; distance_from_low=0; double size_of_wave=(wave_end_price-wave_start_price)/_Point; double size_of_retracement=(wave_end_price-low_mem)/_Point; if(size_of_wave>0.0){ double retraced=(size_of_retracement/size_of_wave)*100.0; double new_wave_size_in_atr_units=((wave_end_price-low_mem)/_Point)/rollingAtr; //--- se o novo tamanho do pacote for válido if(new_wave_size_in_atr_units>=minSizeInAtrUnits){ //--- se a retração for significativa, inicie uma onda descendente if(retraced>=retracement){ //--- iniciar uma nova onda descendente wave_type=-1; //--- preço inicial é o mem alto wave_start_price=high[i-distance_from_high]; wave_start_distance=distance_from_high; //--- o preço final é o novo mínimo wave_end_price=low[i]; wave_end_distance=0; //--- desenhar a onda upWaves[i-wave_start_distance]=high_mem; dwWaves[i]=low[i]; //--- mudar a alta high_mem=high[i]; distance_from_high=0; //--- mudar a baixa low_mem=low[i]; distance_from_low=0; } } } } }
Fazemos o oposto quando temos uma onda de baixa.
E pronto, nosso ziguezague de retração está pronto.
Aqui está o ziguezague com retração de 23,6% e tamanho mínimo de 0,0 das ondas em unidades atr
e aqui está o mesmo ziguezague com tamanho de ondas de 3 minutos em unidades atr
Traduzido do inglês pela MetaQuotes Ltd.
Publicação original: https://www.mql5.com/en/code/56619

O script TradeReportExporter foi projetado para exportar o histórico de negociações (trades) em um conveniente arquivo CSV. Ele coleta automaticamente dados sobre todas as negociações do último ano para o instrumento no qual está instalado. O arquivo inclui dados como data e hora, tipo de transação (compra/venda), preço, volume, comissão e lucro/perda. O resultado é salvo em um arquivo que pode ser aberto no Excel ou em qualquer outro editor de planilhas.

Um utilitário simples para monitorar swaps longos e curtos de um único símbolo. Se os swaps de sua corretora forem especificados em pontos em vez da moeda da conta, esse utilitário converterá automaticamente os pontos em moeda da conta. Os swaps são triplicados na quarta-feira. O alinhamento horizontal e vertical pode ser ajustado nas entradas.

Um indicador de ziguezague que usa uma única entrada para ajustar o tamanho da etapa para detectar mudanças na direção da onda.

O objetivo é tornar a função prontamente disponível para qualquer tarefa de integração do Telegram no desenvolvimento da MQL5. Ao adicionar esse arquivo ao seu CodeBase, você pode simplesmente incluí-lo em seus Expert Advisors e chamar a função diretamente do módulo incluído. Isso elimina a necessidade de desenvolver o código do zero repetidamente, garantindo a reutilização em vários projetos.