O que «determinístico» realmente significa na camada de liquidação

Liquidação determinística é um contrato: o mesmo input sempre deve produzir o mesmo output, para sempre. Dado um registro de aposta e um registro de resultado oficial, a função de liquidação retorna um de três valores — settled, void, pending_review. Sem timestamps na lógica, sem chamadas a Math.random(), sem leituras de estado mutável compartilhado.

Parece óbvio até você ver com que frequência é violado em produção. Um worker que lê o cache de odds para calcular um reembolso de void não é determinístico. Mais contexto na nossa anatomia de integração.

O motor Sporbet Soft impõe o determinismo tratando a liquidação como uma função pura de dois argumentos — versionada e reproduzível.

Passo um: validação de feed fonte antes da execução

Antes que a função de liquidação execute, o motor valida o resultado oficial. O resultado chega de um dos feeds primários (Sportradar/Betradar, Genius Sports, BetGenius) mais um cross-check opcional de um feed secundário. A camada de validação rejeita resultados que falham em qualquer um de cinco gates. Placares discrepantes são sinalizados. Placares conflitantes entre dois feeds são enfileirados para revisão de trading. Resultados que chegam antes do limiar de fim oficial (tipicamente minuto 85 para futebol) são retidos.

Só depois que um resultado passa pelos cinco gates ele se torna input de liquidação. Isso soa como overhead até você lembrar que um evento de feed ruim auto-liquidando um mercado no sentido errado pode custar ao operador mais que a taxa de vendor trimestral.

Passo dois: lookup de template de mercado e seleção de função

Todo mercado que o sportsbook oferece é apoiado por um template de mercado versionado: um documento JSON que captura o nome do mercado, suas seleções, seus parâmetros e — criticamente — uma referência à função de liquidação que sabe como liquidá-lo. Um mercado 1X2 tempo regular aponta para settle_1x2_ft. Um handicap asiático -1.25 aponta para settle_asian_handicap com o parâmetro de linha embutido no bet record.

O template é versionado porque definições de mercado mudam. Quando uma liga muda de morte súbita para formato de prorrogação de duas metades, o template correspondente envia uma nova versão. Uma aposta de cinco anos ainda liquida sob as regras que aplicavam no dia em que foi colocada.

Passo três: execução de função e logging reproduzível

Com o resultado validado e o template selecionado, a função de liquidação executa. A função é um pedaço de código quase puro — pega a aposta, o resultado e opcionalmente a tentativa de liquidação anterior, e retorna a decisão mais o valor do pagamento. Sem I/O, sem leituras de relógio, sem números aleatórios.

Cada execução escreve um evento de liquidação no audit log append-only. Sporbet Soft emparelha o audit log com um harness de replay sintético que re-executa cada liquidação noturnamente contra as últimas versões de função e sinaliza qualquer drift. Em quatro anos de operação pegamos dois bugs reais de liquidação dessa forma antes que qualquer cliente os notasse.

Semântica de void e imutabilidade de seleções já liquidadas

Void é onde motores de liquidação ingênuos desabam. A interpretação intuitiva — «uma partida foi anulada, então vamos reverter tudo» — é perigosa. Se um jogador colocou um acumulador de quatro pernas e a terceira perna já foi liquidada e creditada, anular retroativamente a partida inteira forçaria o motor a clawback crédito de uma wallet que desde então foi gasta ou sacada.

A regra Sporbet Soft é explícita: seleções já liquidadas são imutáveis em void. Quando uma partida é anulada, o motor void apenas as seleções que ainda estão pending no momento em que o void é processado; seleções já settled permanecem settled, e o pagamento multi-bet é recalculado tratando a perna anulada como uma «perna void» com odd efetiva 1.00.

Pelas regras de finalização controladas pelo operador — ver controles de risco operador — void requer um código de razão de uma taxonomia fixa e um ID de usuário operador.

Recálculo multi-bet e reconciliação de cashout parcial

Recálculo multi-bet é uma das features de maior alavancagem no motor. Quando uma única perna de um acumulador liquida, o motor não espera a aposta inteira estar pronta — recalcula incrementalmente a exposição da aposta e a liability aberta do operador.

Cashout parcial adiciona um segundo eixo. Um jogador que faz cashout de 40 % de um acumulador de quatro pernas depois de duas pernas ganhas deixa 60 % da aposta ativa; o motor deve reconciliar o cashout de 40 % contra a wallet, marcar 60 % do stake original como ainda-em-risco e continuar recalculando o multi.

O desafio de engenharia não é a matemática, é a concorrência. Sporbet Soft usa chaves de idempotência derivadas do ID de aposta, ID de perna e contador de tentativa — ver nossa arquitetura de latência de odds.