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:
- 52
- Avaliação:
- Publicado:
- 2025.06.18 12:06
-
Precisa de um robô ou indicador baseado nesse código? Solicite-o no Freelance Ir para Freelance
Este código de consultor especialista examinará o relógio de mercado do corretor do usuário e extrairá símbolos para os quais baixará todos os ticks disponíveis ou ticks até uma data.
Isso pode ajudá-lo a baixar todo o histórico de símbolos para seu backtest ou criar um gráfico personalizado a partir desses ticks.
Os terminais armazenarão os ticks em cache na pasta de dados, portanto, certifique-se de que você tenha espaço suficiente no disco rígido.
Para facilitar o download dos símbolos, precisamos primeiro de um gerenciador de download.
A estrutura CDownloadManager contém todas as informações que precisaremos reter.
struct CDownloadManager { bool m_started,m_finished; string m_symbols[],m_current; int m_index;
- O estado do download (iniciado/concluído)
- a lista dos símbolos a serem verificados
- o símbolo atual
- e o índice do símbolo que está sendo verificado
Também precisaremos ler e gravar no disco rígido e, como estamos trabalhando com símbolos, criamos duas funções rápidas para gravar e ler strings de arquivos binários.
A função salvar string no arquivo :
void writeStringToFile(int f,string thestring) { /salvar a cadeia de símbolos char sysave[]; int charstotal=StringToCharArray(thestring,sysave,0,StringLen(thestring),CP_ACP); FileWriteInteger(f,charstotal,INT_VALUE); for(int i=0;i<charstotal;i++) { FileWriteInteger(f,sysave[i],CHAR_VALUE); } }
Ela recebe :
- identificador de arquivo f, de um arquivo aberto para gravação e sinalizadores binários FILE_WRITE|FILE_BIN
- a cadeia de caracteres a ser gravada no arquivo
Ela escreve um comprimento inteiro de quantos caracteres há na cadeia e, em seguida, armazena cada caractere na cadeia.
A função carregar cadeia de caracteres do arquivo:
string readStringFromFile(int f) { string result=""; //carregar string de símbolo char syload[]; int charstotal=(int)FileReadInteger(f,INT_VALUE); if(charstotal>0) { ArrayResize(syload,charstotal,0); for(int i=0;i<charstotal;i++) { syload[i]=(char)FileReadInteger(f,CHAR_VALUE); } result=CharArrayToString(syload,0,charstotal,CP_ACP); } return(result); }
Recebe:
- identificador de arquivo f de um arquivo aberto para leitura como binário, sinalizadores FILE_READ|FILE_BIN
Ele lê um comprimento inteiro de quantos caracteres devem ser esperados naquele ponto do arquivo, lê cada caractere em uma matriz de caracteres e, em seguida, cria uma cadeia de caracteres a partir dessa matriz de caracteres, que é retornada como resultado do carregamento como uma cadeia de caracteres.
De volta à estrutura do CDownloadManager. Precisamos de uma maneira de inicializar o gerenciador e preenchê-lo a partir da observação do mercado:
//+------------------------------------------------------------------+ //| pegar símbolos da observação do mercado| //+------------------------------------------------------------------+ void grab_symbols() { //! somente do mw ! int s=SymbolsTotal(true); ArrayResize(m_symbols,s,0); for(int i=0;i<ArraySize(m_symbols);i++) { m_symbols[i]=SymbolName(i,true); } }
Bastante simples:
- perguntar quantos símbolos estão na observação do mercado (ativos)
- redimensionar nossa matriz m_symbols para recebê-los
- fazer um loop no total de símbolos e solicitar o nome do símbolo
Também somos responsáveis por gerenciar o download dos dados do símbolo, portanto, precisaremos de uma função que seja essencialmente o gerenciador:
//+------------------------------------------------------------------+ //| Gerenciar o processo de download de símbolos| //+------------------------------------------------------------------+ void manage(string folder,string filename) { //essencialmente, isso inicia ou navega para o próximo símbolo //se definido if(ArraySize(m_symbols)>0) { //se não for iniciado if(!m_started) { m_started=true; //ir para o primeiro símbolo m_current=m_symbols[0]; m_index=1; save(folder,filename); if(_Symbol!=m_current) { ChartSetSymbolPeriod(ChartID(),m_current,_Period); } else { ENUM_TIMEFRAMES new_period=PERIOD_M1; for(int p=0;p<ArraySize(TFS);p++) { if(_Period!=TFS[p]) { new_period=TFS[p]; break; } } ChartSetSymbolPeriod(ChartID(),m_current,new_period); } return; } //se iniciado else { m_index++; if(m_index<=ArraySize(m_symbols)) { m_current=m_symbols[m_index-1]; save(folder,filename); if(_Symbol!=m_current) { ChartSetSymbolPeriod(ChartID(),m_current,_Period); } return; } else { m_finished=true; FileDelete(folder+"\\"+filename); Print("Finished"); ExpertRemove(); return; } } } else { Print("Please grab symbols first"); } //se o conjunto termina aqui }
Como o sistema funciona:
- O gráfico é aberto, precisamos de 1 gráfico, e um cronômetro é definido.
- Esse cronômetro é executado, cancelamos o cronômetro
- Verificamos se esse é um novo download ou um download contínuo
- Se for um novo download, nós o configuramos pegando todos os símbolos
- Se for um download contínuo, baixamos os dados do símbolo atual
Essa é a parte do código que realiza o download no cronômetro:
//+------------------------------------------------------------------+ //|Timer| //+------------------------------------------------------------------+ void OnTimer() { //--- se sincronizado if(SymbolIsSynchronized(_Symbol)&&TerminalInfoInteger(TERMINAL_CONNECTED)==1) { EventKillTimer(); //--- carregar o sistema aqui if(MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE)) { //--- sistema carregado, portanto, estamos verificando um símbolo aqui Comment("System loaded and we are processing "+MANAGER.m_current); //--- tick load //--- encontre primeiro o tique mais antigo disponível no corretor int attempts=0; int ping=-1; datetime cursor=flatten(TimeTradeServer()); long cursorMSC=((long)cursor)*1000; long jump=2592000000;//60*60*24*30*1000; MqlTick receiver[]; long oldest=LONG_MAX; Comment("PleaseWait"); while(attempts<5) { ping=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,cursorMSC,1); if(ping==1) { if(receiver[0].time_msc==oldest) { attempts++; } else { attempts=0; } if(receiver[0].time_msc<oldest) { oldest=receiver[0].time_msc; } cursorMSC-=jump; if(limitDate&&receiver[0].time<=oldestLimit) { break; } } else { attempts++; } Sleep(44); Comment("Oldest Tick : "+TimeToString((datetime)(oldest/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"\nCursor("+TimeToString((datetime)(cursorMSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+")\nAttempts("+IntegerToString(attempts)+")\nPlease wait for response..."); } //--- nesse ponto, temos o tique mais antigo //--- comece a solicitar ticks do mais antigo para o mais recente if(oldest!=LONG_MAX) { ArrayFree(receiver); datetime newest_tick=0; //--- recebe a hora do último tique para esse símbolo armazenado em symbol_time datetime most_recent_candle=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME); while(newest_tick<most_recent_candle) { //--- solicitar um novo lote a partir do tempo mais antigo com o limite de ticks especificado int pulled=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,oldest,tick_packets); if(pulled>0) { //--- se puxarmos um novo lote, atualize nossos tempos baixados newest_tick=receiver[pulled-1].time; oldest=receiver[pulled-1].time_msc; ArrayFree(receiver); } //--- timeout server requests , altere-o se desejar Sleep(44); Comment("Pulled up to "+TimeToString(newest_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" so far"); } } else { Alert("Please close the terminal \n head over to the ticks folder \n and delete the empty folders"); ExpertRemove(); } //--- atualize o gerente e siga em frente MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE); } else { //--- pegue os símbolos do market watch para iniciar o download Comment("Grabbing MW and starting"); MANAGER.grab_symbols(); MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE); } } }
Traduzido do inglês pela MetaQuotes Ltd.
Publicação original: https://www.mql5.com/en/code/56324

Se você estiver executando vários robôs de negociação simultaneamente ou apenas uma estratégia sofisticada, acompanhar o desempenho de cada Expert Advisor pode ser surpreendentemente demorado. O MetaTrader 5 (MT5) exibe convenientemente ordens e posições em sua "Caixa de ferramentas", mas quando vários robôs compartilham a mesma conta, fica mais difícil saber qual EA está gerando seus lucros - ou perdas. Uma única conta pode ter dezenas ou centenas de negociações, cada uma aberta por diferentes EAs, o que torna difícil separar os resultados de um robô dos de outro.

Tempo para fechamento da vela. Cores de texto dinâmicas. Otimizado para back-testing.

Essas são algumas declarações #define que são úteis para executar operações em seu EA. Você só precisa atribuir o nome de suas variáveis no início do arquivo e deixar que as outras instruções #define façam o trabalho. Para usar esse arquivo, adicione #include <DEFINE_statements.mqh> à primeira linha do arquivo do seu EA.

O indicador traça duas linhas. A linha inferior é calculada com base no período mais recente da SMA que causou um salto para cima. A linha superior é calculada com base no período mais recente da SMA que causou um salto para baixo.