Assista a como baixar robôs de negociação gratuitos
Encontre-nos em Telegram!
Participe de nossa página de fãs
Script interessante?
Coloque um link para ele, e permita que outras pessoas também o avaliem
Você gostou do script?
Avalie seu funcionamento no terminal MetaTrader 5
Experts

Download all ticks of a symbol's history - expert para MetaTrader 5

Visualizações:
52
Avaliação:
(4)
Publicado:
2025.06.18 12:06
Freelance MQL5 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

Multiple EA Tracking with a Magic Number Based Profit and Loss Live Dashboard in MQL5 Multiple EA Tracking with a Magic Number Based Profit and Loss Live Dashboard in MQL5

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.

Time To Close v1.01 - MT5 Time To Close v1.01 - MT5

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

Useful #define statements Useful #define statements

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.

Self Optimized SMA Self Optimized SMA

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.