FinTechSep 8, 20268 min de leitura

Checagens de Risco Pré-Negociação Dentro do Caminho da Ordem

Risco Pré-NegociaçãoGestão de riscoInfraestrutura de tradingSistema de Gestão de Ordens
Erro ao carregar a imagem

Limites de posição, margem, limites fat-finger e um kill switch precisam responder em cada ordem antes que ela deixe o gateway. É assim que essas checagens vivem dentro do caminho da ordem em vez de ao lado dele: que estado fica em memória, o que é recalculado de forma incremental e o que acontece depois de um reinício. As restrições vêm primeiro.

Uma ordem chega ao gateway. Antes de sair para a venue, algo precisa decidir se a conta pode enviá-la. Essa decisão roda em cada ordem, inclusive na esmagadora maioria que está perfeitamente em ordem, então seu custo é pago por todo o tráfego normal, e não apenas pelas rejeições.

Essa é a restrição a nomear primeiro. Uma checagem de risco colocada no caminho da ordem é um imposto sobre a entrada de ordens. A pergunta de engenharia não é como deixar a checagem esperta, é como deixá-la pequena o bastante para que os traders não a sintam, e honesta o bastante para que ela ainda recuse as ordens que precisa recusar.

O que realmente pertence ao caminho da ordem

O hot path responde exatamente uma pergunta: esta ordem pode ser enviada agora, dado o que sabemos no momento sobre esta conta. As checagens que respondem a essa pergunta ficam. As que respondem a outra pergunta saem.

  • Limites de posição e de exposição - a posição resultante no instrumento, no grupo e na conta, comparada com os limites configurados
  • Margem ou poder de compra - se a conta ainda tem espaço para a ordem sob o modelo de margem atual
  • Limites fat-finger - tamanho da ordem, nocional e distância de preço em relação a uma referência, pegando o erro de digitação antes que a venue o pegue
  • Estado do instrumento e da conta - negociação suspensa, conta restrita, close-only, produto não habilitado para esta conta
  • Estado do kill switch - uma única flag que sobrepõe tudo acima
  • Proteções contra duplicatas e self-trade onde a venue não as oferece

Todo o resto roda ao lado do caminho, sobre o mesmo estado, sem segurar a ordem. Isso alimenta os limites que o hot path aplica, mas não fica entre o trader e a venue.

  • Analytics de risco de portfólio - rodadas de cenário, testes de estresse, exposição correlacionada entre contas
  • Reavaliação do modelo de margem quando os parâmetros mudam, e qualquer recálculo que toque o book inteiro
  • Vigilância e detecção de padrões, que precisam de um histórico que o hot path deliberadamente não carrega
  • Relatórios, reconciliação e qualquer coisa que converse com um banco de dados ou um serviço externo
  • Análise de crédito e de contraparte, que por natureza opera em um relógio mais lento

A linha divisória é uma pergunta, não uma categoria. No caminho: esta ordem pode sair. Ao lado do caminho: quais deveriam ser os limites. Qualquer coisa que responda à segunda pergunta e ainda assim segure a ordem é um erro de design, por mais importante que a checagem seja.

Onde vive o estado de posição, e por que o banco de dados não fica no caminho

O estado de que uma checagem pré-negociação precisa - posições atuais, ordens ativas, margem usada e disponível, configuração de limites - vive na memória do processo que toma a decisão. Não em um cache na frente de um banco de dados, não atrás de uma chamada de rede. No processo.

A razão não é só velocidade, embora uma consulta seja ordens de grandeza mais cara do que uma busca em um array local. A razão é correção. Um banco de dados guarda a posição como ela foi escrita. A checagem de risco precisa da posição incluindo ordens enviadas há instantes que ainda não foram executadas, confirmadas ou persistidas. Se você lê do armazenamento, você verifica contra um passado que já foi ultrapassado pelo seu próprio fluxo.

Na prática, isso molda o processo do jeito que qualquer componente de baixa latência é moldado:

  • Um escritor por conta. As contas são fragmentadas entre instâncias de risco para que o estado de uma conta nunca tenha contenção, e nenhum lock é tomado no caminho da ordem
  • Estruturas planas e pré-alocadas - arrays de tamanho fixo indexados por id de conta e de instrumento, resolvidos no início da sessão, e não buscas em hash sobre strings montadas por ordem
  • Sem alocação, sem I/O e sem logging que bloqueie no caminho de decisão; o registro de auditoria é passado para outra thread por uma fila
  • Configuração que muda sem reinício é trocada como um snapshot imutável inteiro, então a checagem nunca lê um limite atualizado pela metade

O banco de dados é onde a posição é registrada. Não é onde a posição é conhecida.

Recálculo incremental, não uma passada completa

Um recálculo completo da exposição e da margem de uma conta percorre cada posição e cada ordem ativa. Esse custo cresce com o tamanho do book, o que significa que a checagem de risco ficaria mais lenta justamente para os clientes que mais operam. Por isso o hot path não recalcula. Ele aplica um delta.

A conta carrega agregados correntes - exposição líquida e bruta por instrumento e por grupo, margem usada, nocional em trânsito. Uma ordem que chega produz uma pequena mudança nesses agregados, os valores alterados são comparados com os limites, e a ordem é aceita ou rejeitada. O trabalho é proporcional à ordem, e não à carteira.

  • No envio, o efeito de pior caso da ordem é reservado contra os agregados, para que duas ordens em trânsito não caibam na mesma folga restante
  • Em rejeição, cancelamento ou expiração, a reserva é liberada; em execução, a reserva é substituída pela mudança de posição realizada
  • As execuções parciais ajustam os dois lados disso em um único passo, e é aí que a maior parte dos bugs desse tipo de engine realmente vive
  • Regras de netting e de agrupamento são resolvidas quando o instrumento é carregado, e não por ordem, então o delta é um punhado de operações aritméticas

O recálculo completo continua acontecendo - em um cronograma, quando parâmetros de margem mudam e como autoverificação periódica contra o resultado incremental. Ele roda fora do caminho, sobre uma cópia, e seu resultado ou é trocado ou é levantado como divergência. Um estado incremental que se afasta silenciosamente do estado real é pior do que nenhuma checagem, então a comparação não é opcional.

Medido no caminho de risco que construímos, a checagem pré-negociação em si se completa em <1 ms. Esse número cobre a decisão sobre o estado em memória, não a jornada completa de uma ordem do cliente até a venue e de volta.

O kill switch é um caminho separado

Um kill switch é usado justamente quando algo já está errado. Isso descarta construí-lo sobre a mesma maquinaria que pode ser aquilo que está errado. Ele é um caminho separado, com regras próprias.

  • É uma única flag atômica lida no início da checagem, antes de tocar em estado de posição, margem ou dados do instrumento - então ela funciona mesmo quando esses estão desatualizados, ausentes ou quebrados
  • Ele é acionado por vários gatilhos independentes: uma ação do operador, uma condição automatizada, a perda do feed de dados de mercado ou de execuções do qual o estado de risco depende
  • Ele falha fechado. Se o processo de risco não consegue estabelecer que tem estado válido, o gateway se comporta como se o switch estivesse acionado
  • Ele tem escopos - a firma inteira, uma mesa, uma conta, uma estratégia - porque um switch que só consegue parar tudo acaba sendo usado tarde demais
  • Acioná-lo é uma ação e uma confirmação, não um deploy de configuração; desativá-lo é deliberado e sempre registrado

Parar novas ordens é a metade fácil. A metade difícil é o que o switch faz com as ordens já em repouso na venue: retirar cotações e cancelar ordens ativas precisa ser possível enquanto o caminho de envio está desativado. Esse caminho de cancelamento merece testes próprios, porque ele é exercitado no pior dia, e não em um dia normal.

O reinício, e como o estado volta

O estado em memória é uma visão derivada de um registro durável. É isso que torna um reinício sobrevivível. Todo evento que muda o estado de risco - uma ordem aceita, uma reserva liberada, uma execução aplicada, um limite alterado, o switch acionado - é acrescentado a um journal na máquina local antes de ser efetivado adiante.

  • Na inicialização, o processo reproduz o journal para reconstruir os agregados e depois reconcilia contra o drop copy da venue e da clearing para posições e ordens ativas
  • Enquanto a reconciliação não termina, a conta não está aberta para negociação. Um engine de risco que aceita ordens enquanto ainda está descobrindo a posição não é um engine de risco
  • Uma divergência entre o estado reproduzido e a visão da venue interrompe aquela conta e dispara um alerta; ela nunca é resolvida preferindo silenciosamente um dos lados
  • Um hot standby segue o mesmo journal, então um failover restaura um estado aquecido em vez de um replay a frio, e o standby é verificado sendo promovido regularmente, e não na teoria

O tempo de recuperação passa então a depender do tamanho do journal e da disponibilidade do drop copy, e não do tamanho do book, e o modo de falha de cada incógnita é o mesmo: recusar-se a operar a conta.

O que este design não entrega

Vale enunciar os limites honestos com clareza, porque são eles que decidem se essa arquitetura serve:

  • A checagem só é tão correta quanto o feed de execuções. Se o drop copy ou os relatórios de execução atrasam, a exposição fica subestimada, e a resposta correta é degradar para limites conservadores ou acionar o switch, em vez de seguir operando sobre estado desatualizado
  • Modelos de margem de portfólio genuinamente não aditivos resistem à avaliação incremental. O que funciona é um limite incremental conservador no caminho, mais o modelo completo fora dele; o preço é que algumas ordens são rejeitadas embora o modelo completo as permitisse
  • O switch protege contra o seu próprio fluxo, não contra o mercado. Ele não evita um gap ou uma derrapagem em posições que você já carrega
  • Estado dentro do processo significa que o engine de risco e o gateway de ordens compartilham o mesmo destino. Isso compra latência e custa a capacidade de escalá-los de forma independente
  • A fragmentação por conta com escritor único dificulta os limites entre contas, e checagens no nível da firma precisam de uma camada de agregação mais lenta, com seu próprio atraso
  • Dá mais trabalho operacional do que uma checagem apoiada em banco de dados: journals, reconciliação, ensaios de promoção do standby. Se a entrada de ordens não é sensível a latência, essa complexidade não compensa

A amBrain constrói esse tipo de caminho de risco pré-negociação para corretoras e prop firms, com os hot paths escritos em Rust. O time trabalha com infraestrutura de trading a partir de Yerevan, na Armênia, desde 2019.

Precisa de ajuda para construir isso?

Nosso time de engenharia é especializado em soluções de FinTech. Vamos conversar sobre como dar vida ao seu projeto.

Artigos relacionados

Erro ao carregar a imagem
FinTech
Sep 8, 20269 min de leitura

Projetando um Matching Engine em Rust: Price-Time Priority Sem Pausas de GC

Ler post
Erro ao carregar a imagem
FinTech
Apr 27, 202618 min de leitura

Relatório de Infraestrutura de Trading 2026: Cazaquistão, Uzbequistão, Armênia, Geórgia

Ler post
Erro ao carregar a imagem
FinTech
Mar 14, 202612 min de leitura

Por que os milissegundos importam: um guia simples sobre latência em plataformas de trading

Ler post