//+------------------------------------------------------------------+ //| Test_ChartSaveTemplate.mq5 | //| Copyright 2000-2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2000-2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property script_show_inputs //--- parâmetros de entrada input string symbol="GBPUSD"; // O símbolo do novo gráfico input ENUM_TIMEFRAMES period=PERIOD_H3; // O prazo do novo gráfico //+------------------------------------------------------------------+ //| Programa Script da função start (iniciar) | //+------------------------------------------------------------------+ void OnStart() { //--- Primeiros indicadores anexados ao gráfico int handle; //--- Preparar indicador para uso if(!PrepareZigzag(NULL,0,handle)) return; // Falhou, sair //--- Anexar o indicador ao atual gráfico, mas em janela separada. if(!ChartIndicatorAdd(0,1,handle)) { PrintFormat("Falha para anexar no gráfico %s/%s um indicador com o handle=%d. Código de erro %d", _Symbol, EnumToString(_Period), handle, GetLastError()); //--- Finalizar a operação do programa return; } //--- Atualizar o gráfico para ver o indicator ChartRedraw(); //--- Encontre as duas últimas fracturas do zigzag double two_values[]; datetime two_times[]; if(!GetLastTwoFractures(two_values,two_times,handle)) { PrintFormat("Falha para localizar duas últimas fracturas no ZigZag!"); //--- Finalizar a operação do programa return; } //--- Anexar agora um canal de desvio padrão string channel="StdDeviation Channel"; if(!ObjectCreate(0,channel,OBJ_STDDEVCHANNEL,0,two_times[1],0)) { PrintFormat("Falha ao criar objeto %s. Código de erro %d", EnumToString(OBJ_STDDEVCHANNEL),GetLastError()); return; } else { //--- O canal foi criado, definir o segundo ponto ObjectSetInteger(0,channel,OBJPROP_TIME,1,two_times[0]); //--- Define uma dica de contexto (tooltip) para o canal ObjectSetString(0,channel,OBJPROP_TOOLTIP,"Demonstração no ajuda MQL5"); //--- Atualizar o gráfico ChartRedraw(); } //--- Salve o resultado em um template (modelo) ChartSaveTemplate(0,"StdDevChannelOnZigzag"); //--- Abrir um novo gráfico e aplicar um modelo salvo a ele long new_chart=ChartOpen(symbol,period); //--- Habilitar uma dica de contexto (tootips) para objetos gráficos ChartSetInteger(new_chart,CHART_SHOW_OBJECT_DESCR,true); if(new_chart!=0) { //--- Aplicar uma template (modelo) salvo para o gráfico ChartApplyTemplate(new_chart,"StdDevChannelOnZigzag"); } Sleep(10000); } //+------------------------------------------------------------------+ //| Cria um manipulador ziguezague e garante disponibilidade de seus dados| //+------------------------------------------------------------------+ bool PrepareZigzag(string sym,ENUM_TIMEFRAMES tf,int &h) { ResetLastError(); //--- O indicador de ziguezague deve estar localizado em terminal_data_folder\MQL5\Examples h=iCustom(sym,tf,"Examples\\Zigzag"); if(h==INVALID_HANDLE) { PrintFormat("%s: Falha ao criar manipulador do indicador Zigzag. Código de erro %d", __FUNCTION__,GetLastError()); return false; } //--- Quando é criado um manipulador de indicador, requer tempo para calcular valores int k=0; // O número de tentativas de espera para o cálculo de indicadores //--- Aguarda até que o cálculo faça um loop (volta completa), pausando por 50 milissegundos se o cálculo ainda não está pronto while(BarsCalculated(h)<=0) { k++; //--- Mostrar o número de tentativas PrintFormat("%s: k=%d",__FUNCTION__,k); //--- Espera 50 milissegundos até que o indicador seja calculado Sleep(50); //--- Se mais de 100 tentativas, então algo está errado if(k>100) { //--- Reportar um problema PrintFormat("Falha ao calcular o indicador para %d tentativas!"); //--- Terminar a operação do programa return false; } } //--- Tudo está pronto, o indicador é criado e os valores são calculados return true; } //+------------------------------------------------------------------+ //|Busca para as últimas duas fracturas de zigzag e lugar para arrays| //+------------------------------------------------------------------+ bool GetLastTwoFractures(double &get_values[],datetime &get_times[],int handle) { double values[]; // Uma array para os valores de ziguezague datetime times[]; // Uma array para obter tempo int size=100; // Tamanho da array ResetLastError(); //--- Copiar os últimos 100 valores do indicador int copied=CopyBuffer(handle,0,0,size,values); //--- Conferir o número de valores copiados if(copied<100) { PrintFormat("%s: Falha para copiar valores %d do indicador com o handle=%d. Código de erro %d", __FUNCTION__,size,handle,GetLastError()); return false; } //--- Definir a ordem de acesso para a array como um tempo de series (timeseries) ArraySetAsSeries(values,true); //--- Escreva aqui o número de baras, em que foram encontradas fracturas int positions[]; //--- Definir tamanhos de array ArrayResize(get_values,3); ArrayResize(get_times,3); ArrayResize(positions,3); //--- Contadores int i=0,k=0; //--- Comece a procurar por fracturas while(i<100) { double v=values[i]; //--- Nós não estamos interessados em valores vazios if(v!=0.0) { //--- Relembra o número de barras positions[k]=i; //--- Relembra o valor do zigzag sobre a fractura get_values[k]=values[i]; PrintFormat("%s: Zigzag[%d]=%G",__FUNCTION__,i,values[i]); //--- Aumentar o contador k++; //--- Se duas fraturas encontrados, quebrar o loop (ciclo) if(k>2) break; } i++; } //--- Definir a ordem de acesso às arrays como nas séries de tempo (timeseries) ArraySetAsSeries(times,true); ArraySetAsSeries(get_times,true); if(CopyTime(_Symbol,_Period,0,size,times)<=0) { PrintFormat("%s: Falha ao copiar valores %d a partir CopyTime(). Código de erro %d", __FUNCTION__,size,GetLastError()); return false; } //--- Abra o tempo da abertura da barra, que ocorreu nas duas últias fracturas get_times[0]=times[positions[1]];// O último, mas um valor será escrito como a primeira fractura get_times[1]=times[positions[2]];// O valor em terceiro lugar, a partir do final será a segunda fractura PrintFormat("%s: primeiro=%s, segundo=%s",__FUNCTION__,TimeToString(get_times[1]),TimeToString(get_times[0])); //--- Bem sucedido return true; } |