Como funcionam as corretoras de criptomoedas (tecnicamente)?

Bot Cripto

Como funcionam as corretoras de criptomoedas (tecnicamente)?

Luiz Duarte
Escrito por Luiz Duarte em 02/12/2022
Junte-se a mais de 34 mil devs

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

Revisado em 14/04/2026!

Desde 2017, quando comecei a investir em criptomoedas, que as corretoras cripto me fascinam. Eu fui de mero investidor a desenvolvedor de integrações, como bots trader, e mais recentemente comecei a estudar mais a fundo a arquitetura e funcionamento das mesmas. Neste artigo, que é o primeiro de outros que pretendo escrever, eu quero trazer um pouco de luz aos elementos mais comuns e ao mesmo tempo mal compreendidos de todas exchanges: o Order Book e o Match Engine.

Importante ressaltar que me refiro aqui às corretoras centralizadas e em estilo “marketplace”, como a Binance, onde compradores e vendedores lançam suas ordens e fecham negócios intermediados pela mesma. Digo isso porque existem corretoras no estilo “casa de câmbio”, onde você compra e vende as moedas para a própria exchange, ao invés de para outras pessoas e também existem as corretoras descentralizadas (dex) que não possuem order books, mas liquidity pools ao invés disso, cuja mecânica é completamente diferente do que vou trazer aqui. Existe ainda um quarto tipo que são as corretoras P2P, que também não abordaremos hoje.

Além disso, ao invés de apenas trazer a teoria, este vai ser um artigo bem técnico e prático, onde construíremos protótipos de algumas partes interessantes para o aprendizado.

Para ter um overview da parte teórica, você pode conferir o vídeo abaixo.

YouTube player

Dito isso, vamos lá!

#1 – Ordens

O restante deste material pode ser visto no vídeo abaixo, que contém o mesmo conteúdo.

Imagine que você tem 1 BTC e quer vender ele a um valor x. Você poderia anunciar ele em algum site de classificados, tipo OLX, e esperar um interessado te chamar. No entanto, na hora de fechar o negócio, você iria transferir o BTC primeiro ou a pessoa iria transferir a grana? Temos aqui um claro risco de confiança, certo? Esse é um dos motivos que as exchanges de criptomoedas existem: para intermediar as transações (trades) de maneira segura, cobrando uma pequena taxa por este serviço. Ambos transferem seus recursos para contas na corretora e ela faz a troca dos valores, que depois podem ser sacados novamente.

Uma primeira forma de entender as exchanges é justamente como um site de classificados de compra e venda de criptomoedas. Esse classificado é organizado através de order books ou livros de ordens. Um order book possui duas páginas: uma para registrar as intenções de compra e outra para as intenções de venda, ambas a preço futuro. Assim, sempre que uma pessoa quer vender, ela envia uma ordem de venda para a página de vendas, declarando a sua intenção, e o mesmo para o caso de querer comprar.

Antes da gente entrar em mais detalhes do OrderBook, vamos falar um pouco dessas ordens em si, sejam de compra ou de venda. Abaixo um exemplo fictício em JS.

Nesta classe para ordens, eu gero ids autoincrementais a cada nova ordem instanciada, além de pegar o instante da máquina para registrar quando ela foi criada. Já o usuário precisa informar o side (buy ou sell), a quantidade e o preço (opcional). Para simplificar, vamos ignorar aqui que uma corretora pode ter várias moedas e combinações entre elas, vou tratar aqui como se fosse apenas BTC negociado em dólar sempre, ok?

Eu adicionei algumas validações importantes nos inputs do usuário antes de guardar os valores nas propriedades e também criei uma constante para os sides das ordens, a fim de que não seja escrito errado por engano.

Toda vez que alguém quiser comprar ou vender uma moeda, o primeiro passo é instanciar uma nova ordem e enviá-la para a corretora. Essa ordem vai parar no order book, de venda ou de compra.

Curso Web3 para Iniciantes
Curso Web3 para Iniciantes

#2 – Livro de Ordens

Existem ordens de market making, ou seja, que ajudam a criar o mercado de negociação. Essas ordens são aquelas a preço futuro, ou seja, pessoas querendo vender mais caro do que o preço médio da moeda atual, ou pessoas querendo comprar mais barato do que o preço médio atual. Toda vez que uma ordem dessas é enviada, ela é registrada no book de compra e ou de venda daquele ativo, para que seja executada mais tarde, formando o mercado da exchange. Uma exchange sem mercado não atrai atenção de ninguém, por isso que muitas vezes elas dão incentivos para estes tipos de ordens, como descontos em taxas ou até isenção.

Importante ressaltar que o order book não é uma fila de ordens, mas sim uma pilha ordenada, onde as ordens mais relevantes ficam no topo e as menos relevantes ficam na base. No caso do order book de compras, as ordens mais relevantes são as que estão querendo pagar mais, enquanto que book de vendas, é a ordem que está mais barata. Havendo empate, a ordem de chegada no book resolve o impasse, com os mais antigos tendo prioridade. Assim, toda vez que chegar uma nova ordem, deve ser verificado em que posição da pilha do book ela deve ficar, conforme seu preço.

Vamos começar criando nossa classe OrderBook.js como abaixo:

Aqui eu defini o construtor, que inicializa os books de compra e de venda e uma função getTickerPrice, que descobre o preço médio deste ativo no mercado atualmente. Como ele sabe isso? Olhando o ponto central entre a melhor oferta de compra e de venda!

Vamos criar agora a função que adiciona uma nova ordem do book correspondente.

A adição das ordens é bem direta, no book correto, enquanto que a ordenação eu implementei aqui uma abordagem “ingênua”, que obviamente não possui uma boa performance pois ela reordena todo o book toda vez que chega uma nova ordem. Como uma melhoria futura, o book deveria ser uma lista encadeada (linked list), que mantém sequência e é muito melhor para inserir elementos em posições arbitrárias mantendo a ordenação correta.

No entanto, do jeito que está nosso order book ele serve apenas para registrar as ordens, certo? Quando que de fato elas deixam de ser apenas ordens e se tornam trades?

Curso Node.js

#3 -Match Maker ou Match Engine

Mas a função do order book não é apenas para registrar as ordens, mas para que um elemento crucial da arquitetura de qualquer exchange possa funcionar: o match maker ou match engine, como preferir. Isso porque toda vez que uma ordem chega no order book, ela pode disparar a execução de uma ordem que estava no book contrário. Ou seja, uma nova ordem de compra pode acabar executando uma venda que estava pendente e vice-versa. Tudo vai depender, é claro, do preço que a outra parte está pedindo.

A execução de um par de ordens resulta no que chamamos de Trade, como no exemplo abaixo, onde temos o id de ambas ordens, o preço acordado, a quantia executada e o timestamp em que o trade aconteceu. Importante ressaltar que a quantidade não precisa ser igual entre comprador e vendedor, pode haver execução parcial de ordens, com o restante sendo atualizado na ordem do book como veremos mais à frente.

O match engine em si deve manter registro dos trades realizados (já que não estamos usando banco) e de algumas estatísticas de execução que são úteis aos investidores como volume total negociado, preço máximo e preço mínimo já executados, etc como abaixo. Também incluí uma função que retorna os últimos trades realizados.

Agora o ponto alto do match engine é a função de match das ordens. É ela que vai procurar os possíveis casamentos do book de compra com o de venda, sempre olhando somente para as ordens ao topo dos books, onde sempre teremos quatro possibilidades:

  • a ordem de compra mais relevante não cobre o preço da ordem de venda mais relevante, nada acontece;
  • a ordem de compra possui preço igual ou superior à de venda e a quantidade é igual, o trade é realizado e ambas são removidas do book;
  • a ordem de compra possui preço aderente à de venda, mas a quantidade à venda é mais do que o comprador deseja. Neste caso, a ordem de compra é removida e a de venda é atualizada com a quantidade restante;
  • a ordem de compra possui preço aderente à de venda, mas a quantidade à venda é menos do que o comprador deseja. Neste caso, a ordem de venda é removida e a ordem de compra é atualizada com a quantidade restante e re-testada com a próxima ordem de venda mais relevante;

Os cenários de compras parciais que citei acima também podem acontecer ao inverso, com a ordem de venda chegando no match engine e não tendo gente suficiente querendo comprar tudo. Mas como traduzir isso em software? Vamos a um exemplo abaixo, na classe MatchEngine.

Aqui temos a implementação das regras descritas anteriormente, com o adendo de registro do trade no array histórico e os cálculos das estatísticas de mercado, úteis aos investidores.

Agora como usamos essa função? Para isso, temos de voltar ao Order Book. Vamos receber uma instância de matchEngine no construtor, para usarmos inversão de controle e com isso diminuir o acoplamento entre os dois.

Agora vamos criar uma função getStats que traz os dados de mercado do order book e do match engine, juntos.

E por fim, no addOrder, vamos verificar quando o matchEngine precisa ser acionado, e então chamá-lo após a adição da ordem e rebalanceamento do book.

Repare a passagem do this para o matchOrders, para que ele consiga ter acesso aos books e fazer as verificações.

Com isso, agora temos todos os elementos para simular minimamente como uma exchange funciona. Claro, aqui não temos carteiras com fundos e nem diferentes ativos ou tipos de ordens, mas o núcleo está aqui.

Curso Web23
Curso Web23

#4 – Simulando a Exchange

Para vermos se está realmente funcionando, que tal criarmos uma aplicação console? Coloque as suas classes todas em uma pasta lib e crie um arquivo index.js na raiz da aplicação, com os imports abaixo.

Como vamos executar no terminal, eu vou criar algumas funções auxiliares para imprimir os dados minimamente formatados. Abaixo, uma função de impressão de order book e suas estatísticas.

Agora uma função que imprime os últimos trades realizados.

Com as funções de formatação prontas, precisamos de algumas funções para gerar ordens aleatórias, simulando o funcionamento de uma exchange real. Abaixo eu propus funções para gerar preço aleatório, quantidade aleatórias e a ordem inteira.

Agora vou criar uma função sleep, para ocasionar um atraso proposital no sistema. Sem esse recurso não, conseguiríamos ver as atualizações no terminal de tão rápido que ficaria. Também inicializo logo em seguida o order book e o match engine, que usaremos na simulação.

Por fim, vamos fazer um laço de repetição para a geração e submissão das ordens aos order book, chamando as funções de impressão para o usuário ter algo para analisar na tela enquanto tudo é processado.

Execute o programa e você terá após alguns segundos algo como abaixo.

Claro, muita coisa pode ser melhorada e esta abordagem tem alguns problemas crônicos de escala, mas espero que tenha sido uma boa introdução ao assunto e espero que em outra oportunidade eu possa me aprofundar mais neste tema.

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 *