Como obter preços históricos de criptomoedas na Binance com JS

Bot Cripto

Como obter preços históricos de criptomoedas na Binance com JS

Luiz Duarte
Escrito por Luiz Duarte em 28/01/2025
Junte-se a mais de 34 mil devs

Entre para minha lista e receba conteúdos exclusivos e com prioridade

Em outras oportunidades aqui no blog e também no meu canal do Youtube eu trouxe tutoriais de como criar robôs de criptomoedas, ou seja, automações via software para comprar e vender criptoativos em corretoras como Binance, Mercado Bitcoin e BityPreço. Operar com robôs traz inúmeros benefícios, dentre eles a quantidade maior de ofertas que você pode aproveitar, o que faz com que o seu volume total negociado seja facilmente muito maior que a média dos investidores, o que impede um controle manual eficaz das negociações e do PnL (profits and losses). Isso se torna um problema especialmente quando você tem de pagar imposto de renda sobre o lucro obtido nas transações, situação em que você precisará das cotações históricas das moedas não apenas em seu valor original, como em Reais (BRL) também.

Para ajudar nesta e em outras situações que você precise de preços históricos de criptomoedas, no tutorial de hoje vou te mostrar como usar as APIs da Binance para, com um pouco de lógica de programação, consigamos recuperar o preço aproximado pago por um ativo em determinado período do tempo. Se preferir, você pode assistir ao vídeo abaixo ao invés de ler, é o mesmo conteúdo.

Vamos lá!

#1 – Setup do Projeto

Dentre os players mundiais de criptomoedas, uma das mais agressivas em termos de taxas e portfólio de moedas é a Binance, considerada a maior exchange de criptomoedas do mundo em volume de negociações. Usaremos ela como fonte de dados aqui pois é um bom termômetro do mercado de criptomoedas, mas o que vou mostrar pode ser usado com qualquer exchange (de cripto ou não) que disponibilize publicamente o seu histórico de velas. Nem mesmo você precisa ter conta na Binance para fazer este tutorial, pois ele não efetuará as compras e vendas, ok?

Dito isso, antes de sairmos programando precisamos configurar nosso projeto. Usarei aqui a linguagem JavaScript, então precisamos do Node.js instalado na máquina. Se ainda não tem o ambiente de desenvolvimento para Node.js configurado, você pode ver como fazer no vídeo abaixo.

Agora crie uma pasta no seu computador com o nome de binance-historic-price e dentro dela rode o comando abaixo pelo seu terminal de linha de comando para inicializar um projeto Node.js na pasta.

Agora coloque um arquivo index.js vazio dentro da pasta e vamos instalar um pacote via NPM pra deixar nosso projeto preparado. Segue o comando de instalação:

O módulo axios serve para fazer chamadas HTTP às APIs da corretora na sua aplicação Node.js, pois precisaremos de vários dados diferentes. Crie um arquivo index.js na raiz da sua aplicação e para inicializar nosso projeto a partir dele, modifique o seu package.json para que no script de start ele execute:

Esse projeto vai ser uma aplicação console, então vamos deixar nosso index.js já com o pacote que instalamos carregado e com um objeto de interação via terminal inicializado, como abaixo.

Repare que estou usando o pacote readline que é nativo do Node (não requer instalação). Além disso, estou pegando a variação dele com promises, para nosso código ficar mais elegante. Com isso, nosso setup inicial está finalizado.

Livro Node.js

#2 – Obtendo as Informações Básicas

Vamos começar nossa programação através de uma função que servirá para o usuário interagir com a aplicação, fornecendo os dados que precisaremos. Como a ideia é fornecer a cotação histórica de uma criptomoeda na Binance tanto no seu valor original quanto no seu valor em moeda fiduciária, precisaremos do par de moedas, da moeda fiat e da data da cotação, como abaixo.

Nesta amostra de código eu limpo o terminal e peço ao usuário, usando o readline, que informe o par da moeda (BTCUSDT, por exemplo), a sigla ISO da moeda fiat (BRL) e a data da cotação, no formato yyyy-mm-dd, formato este que eu valido depois para evitar problemas com as APIs. Experimente rodar este código do jeito que está e você já terá a experiência de input de dados na aplicação.

Agora precisaremos obter as informações de todos os pares de moedas (symbols) existentes na corretora, para que possamos usar esta informação depois. Para isso, vou criar um array global de symbols e uma função que popula ele.

Aqui eu uso o Axios para ir até a API Exchange Info e pegar as informações que queremos. Basicamente eu preciso do base e do quote de cada symbol, ou seja, da moeda à esquerda e à direita do par. Como não existe uma separação clara no nome dos pares, ou seja, BTCUSDT poderia ser as moedas BTCU e SDT ou as moedas BTC e USDT (o correto nesse caso), precisamos dessas informações para entender as partes que compõem o par de moedas informado pelo usuário. Se quiser saber tudo sobre a API Exchange Info, o vídeo abaixo te ensinar.

Essa função deve ser chamada dentro da start, como abaixo.

Eu incluí um try/catch pois as chamadas às APIs da Binance podem gerar erros que você só conseguirá resolver se tiver acesso à mensagem corretamente, que é o que faz aquela linha de código. Caso estruturas try/catch sejam uma novidade para você, recomendo este artigo (inclui vídeo).

Se quiser fazer testes preliminares, pode usar console.log para ver o que trouxe nessa chamada, imprimindo o conteúdo do array allSymbols.

Curso Node.js e MongoDB

#3 – Obtendo o preço original

Tem dois preços que vamos ter de obter aqui, o original e o convertido para moeda fiduciária. Isso porque em alguns relatórios, como o necessário ao Imposto de Renda Pessoa Física (IRPF) brasileiro, as cotações devem estar sempre em R$ (BRL), mas vamos falar melhor disso depois. Primeiro, vamos nos focar em pegar a cotação original de um ativo em uma data específica. Para isso, vamos criar a função abaixo no mesmo arquivo.

Neste trecho de código eu recebo o par de moedas (symbol) e o timestamp da cotação que eu quero. Então eu vou na API de velas históricas da Binance (klines) e peço pra ele apenas 1 vela diária para o par em questão no instante em questão. Do resultado eu pego apenas a primeira vela (data[0]) e da vela em questão eu pego o instante de abertura (data[0][0]) e o preço de fechamento (data[0][4]), já convertido para número decimal.

Essa função nós vamos usar lá no start, logo após o carregamento do allSymbols, como abaixo.

Aqui eu pego o objeto do symbol, que será útil logo mais, peço a cotação do symbol e instante em questão e imprimo algumas informações no console. Experimente testar agora, informando BTCUSDT, BRL e 2024-12-31, você deve obter como retorno a cotação USDT 93576, que era o preço do BTC em USDT no fechamento do ano de 2024.

Mas e o BRL, o que fizemos com essa informação?

Nada ainda, mas isso muda agora.

Curso Web3 para Iniciantes

#4 – Obtendo o preço fiat

Quando o par de moeda que você está consultando é com a sua moeda fiat, não há mais nada que precise ser feito, pois a cotação que você precisa já foi obtida. No entanto, muitas vezes não negociamos em BRL aqui no Brasil. Eu mesmo negocio muito mais em USDT, mas na hora da declaração, preciso trazer tudo para BRL o que é uma dor de cabeça danada saber a conversão exata no dia da compra, que é o que a IN1888 de cripto no IRPF exige.

Mas esta não é uma lógica trivial de conversão, porque temos quatro cenários possíveis, cada um exigindo uma lógica diferente:

  1. se o par já era com moeda fiat, já está certo, basta exibi-lo;
  2. se o par era com stablecoin em dólar, pegamos este valor primeiro e depois a cotação da stablecoin em fiat no dia em questão;
  3. se o par era com cripto, verificamos se exite conversão direta da cripto para fiat, pois se houver, podemos pegar essa cotação no dia em questão;
  4. se o par era com cripto e não tem conversão direta pra fiat, temos de “triangular” com uma stablecoin primeiro.

Para implementar estas 4 lógicas vamos criar uma função calcFiatPrice como abaixo, que comento na sequência.

Eu começo carregando um array com algumas stablecoins pareadas com dólar, adicione mais conforme o que você costuma transacionar.

Depois, eu declaro a função calcFiatPrice recebendo por parâmetro o objeto symbol (oriundo do array allSymbols), a sigla da fiat (BRL), o preço original do par e o timestamp da cotação. Com essas informações, conseguimos fazer testes para entender em qual dos 4 cenários nossa cotação se encontra. Se for no primeiro, onde a moeda à direita do par é a própria fiat, não há nada a ser feito e retornamos o mesmo preço original. Exemplo para teste: BTCBRL

No segundo cenário, nosso symbol tem uma stablecoin à direita do par (ex: BTCUSDT), logo, precisamos pegar a cotação da stablecoin em fiat e depois multiplicar ambos. Aqui eu sempre pego a cotação em USDT+fiat pois é a maior stablecoin de todas e faz par com todas fiats, isso evita possíveis erros de alguma stablecoin que não tenha par com BRL, por exemplo.

No terceiro cenário, temos um par de cripto + cripto, mas a segunda cripto (à direita) possui par com a fiat na Binance, ou seja, posso pegar uma cotação de maneira tão simples quanto se fosse uma stablecoin. Por exemplo, você pode testar com BNBBTC.

E por fim, temos um par de cripto + cripto, mas a segunda cripto não tem par com a fiat, exigindo duas conversões: a primeira da cripto para stablecoin e a segunda da stablecoin para fiat. Aqui novamente eu uso a USDT para as conversões, já que ela é a maior stablecoin do mundo e faz par com todas criptomoedas praticamente. O resultado basta multiplicar tudo. Por exemplo, você pode testar com BNBEUR (Ok, EUR não é cripto, mas não converte para BRL, então funciona como teste).

Para usar nossa função calcFiatPrice, precisamos colocar ela na nossa função start, dentro do bloco try junto dos demais códigos.

É uma chamada bem simples, que não requer grandes explicações. Agora teste o seu projeto com o comando abaixo no terminal.

O resultado, você vê no seu terminal. Na imagem abaixo, o meu teste para obter a cotação de BNBEUR no último dia do ano de 2024 (lembre-se que UTC tem 3h a mais que o Brasil), com as cotações em EUR e BRL após algumas conversões intermediárias.

Um abraço e até a próxima!

Curso Beholder
Curso Beholder

TAGS:

Olá, tudo bem?

O que você achou deste conteúdo? Conte nos comentários.

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *