MetaTrader5
Baixe Todo o Histórico de Ticks de um Símbolo no MetaTrader 5
Se você é trader e utiliza o MetaTrader 5, vai adorar essa dica! Com um sistema de download que desenvolvemos, você pode escanear a lista de símbolos do seu corretor e baixar todos os ticks disponíveis, ou até mesmo até uma data específica.
Isso é extremamente útil para quem quer fazer backtests ou criar gráficos personalizados a partir desses dados de ticks.
Lembre-se de que os ticks serão armazenados na pasta de dados do terminal, então, não esqueça de verificar se há espaço suficiente no seu HD.
Para facilitar o download dos símbolos, começamos com um gerenciador de downloads. A estrutura CDownloadManager contém todas as informações necessárias que vamos utilizar.
struct CDownloadManager
{
bool m_started, m_finished;
string m_symbols[], m_current;
int m_index;
}
O que essa estrutura guarda?
O estado do download (iniciado/terminado)
A lista de símbolos a serem escaneados
O símbolo atual
O índice do símbolo que está sendo escaneado
Precisaremos também de funções para ler e escrever no HD, pois estamos lidando com símbolos. Então, criamos duas funções rápidas para gravar e ler strings de arquivos binários.
Função para salvar uma string em um arquivo:
void writeStringToFile(int f, string thestring)
{
//salva a string do símbolo
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);
}
}
Essa função recebe:
O manipulador do arquivo f, que deve estar aberto para escrita e com a flag binária FILE_WRITE|FILE_BIN
A string que você deseja escrever no arquivo
Ela grava um inteiro que representa a quantidade de caracteres na string e depois armazena cada um deles.
Função para carregar uma string de um arquivo:
string readStringFromFile(int f)
{
string result = "";
//carrega a string do 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);
}
Essa função recebe:
O manipulador do arquivo f, que deve estar aberto para leitura como binário, com as flags FILE_READ|FILE_BIN
Ela lê um inteiro que representa a quantidade de caracteres que você pode esperar naquele ponto do arquivo. Em seguida, lê cada caractere e o coloca em um array de caracteres, criando uma string a partir desse array, que é retornada como resultado.
Agora, vamos voltar à estrutura CDownloadManager. Precisamos de uma forma de inicializar o gerenciador e preenchê-lo a partir da lista de símbolos:
//+------------------------------------------------------------------+
//| Captura os símbolos da lista de mercado |
//+------------------------------------------------------------------+
void grab_symbols()
{
//! apenas da lista de mercado!
int s = SymbolsTotal(true);
ArrayResize(m_symbols, s, 0);
for(int i = 0; i < ArraySize(m_symbols); i++)
{
m_symbols[i] = SymbolName(i, true);
}
}
É bem simples:
Pede quantos símbolos estão na lista de mercado (ativos)
Redimensiona nosso array m_symbols para acomodá-los
Faz um loop pelos símbolos e solicita o nome de cada um
Agora, precisamos gerenciar o download dos dados dos símbolos, então, precisamos de uma função que seja essencialmente o gerenciador:
//+------------------------------------------------------------------+
//| Gerencia o processo de download dos símbolos |
//+------------------------------------------------------------------+
void manage(string folder, string filename)
{
// essencialmente, isso inicia ou navega para o próximo símbolo
// caso esteja definido
if(ArraySize(m_symbols) > 0)
{
// se não começou
if(!m_started)
{
m_started = true;
// vai 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 começou
else
{
m_index++;
if(m_index
2025.02.22