Sob o capô

Como funciona o LotteryCortex

LotteryCortex combina quatro técnicas normalmente usadas só por quants e data scientists. Tornamo-las acessíveis a quem compra um bilhete.

Esta página descreve cada algoritmo que o LotteryCortex executa — da ingestão de dados à seleção de bilhetes. Tudo é abertamente documentável: para cada passo nomeamos o ficheiro-fonte na base de código. Não é uma solução milagrosa, mas a pilha de análise de lotaria mais completamente documentada publicamente que conseguimos construir.

A pipeline em 7 passos

Cada sorteio percorre esta cadeia. Detalhes por algoritmo mais abaixo.

  1. 01

    Ingestão de dados e deteção de anomalias

    Por lotaria fazemos scrape dos arquivos oficiais (fetch HTML direto com fallback Firecrawl). Cada novo sorteio passa por detectDrawAnomaly(): verificação de forma, intervalo, duplicados e comparação qui-quadrado contra os últimos 200 sorteios. Sorteios suspeitos são bloqueados antes de tocar o histórico.

  2. 02

    Engine-core: seis sinais base

    engine-core.ts calcula seis pontuações independentes por número (Bayes, EMA × 3 meias-vidas, PMI, Markov), normaliza-as em postos e combina-as com pesos afinados numa pontuação de ensemble.

  3. 03

    Meta-learner e stacking GBM

    As seis pontuações do motor + 6 features derivadas (interações, recência, hot/cold streaks) alimentam uma regressão logística por lotaria (meta-learner.ts) e um modelo gradient boosted stumps (gbm.ts). O blender empilhado combina ambos out-of-fold sem fuga.

  4. 04

    Geração de bilhetes com anti-clustering

    Amostramos milhares de bilhetes candidatos entre os números melhor pontuados, mas rejeitamos tudo o que tenha demasiado clustering: máx 3 da mesma década, paridade dentro da banda histórica, soma dentro da banda IQR de sorteios reais.

  5. 05

    Otimização de portefólio

    Seleção greedy submodular (portfolio-optimizer.ts) + seletor Markowitz de mínima variância (markowitz.ts) escolhem K bilhetes que juntos cobrem a maior massa de probabilidade com sobreposição mínima.

  6. 06

    Correção de popularidade e EV gating

    popularity.ts penaliza combinações 'bonitas' (aniversários ≤ 31, sequências consecutivas, metade inferior) porque ao acertar é preciso partilhar. ev-gating calcula EV ciente do jackpot por 1 € apostado e dá conselho 'jogar' ou 'saltar'.

  7. 07

    Backtest walk-forward e auto-tuning

    Todos os domingos corre uma validação cruzada k-fold aninhada (nested-cv.ts) mais uma grid-search sobre pesos do motor e presets de meias-vidas. Um bandido Thompson-sampling (bandit.ts) seleciona online o preset de melhor desempenho com base no ROI realizado.

Índice — 20 algoritmos

Algoritmos em detalhe

1. Encolhimento bayesiano de frequências

Quantas vezes um número foi sorteado, corrigido pela quantidade de dados disponíveis.

  • A frequência bruta sobrestima números 'quentes' quando o histórico é curto. Sobrepomos um prior de Dirichlet com estimação automática de alfa (dirichletAlphaAuto, método dos momentos sobre a variância empírica).
  • O resultado é uma probabilidade a posteriori por número que encolhe para 1/N (uniforme) enquanto o histórico é pequeno e segue a verdadeira frequência quando há sorteios suficientes.
p̂(n) = (count(n) + α) / (totalDraws · k + α · N)

src/lib/engine-core.ts · src/lib/advanced-stats.ts

2-4. EMA ponderado no tempo com múltiplas meias-vidas

Sorteios recentes pesam mais que antigos — três horizontes em paralelo.

  • Para cada sorteio i a partir do fim atribuímos peso w_i = 0.5^(i / H). Corremos três EMAs em paralelo com H = 8, 26 e 78 sorteios (curto/médio/longo).
  • Meia-vida curta capta 'hot streaks'. Meia-vida longa evita reagir em excesso a um sorteio estranho. O blender de ensemble decide quanto peso cada horizonte tem por lotaria — afinado por grid-search.
EMA_H(n) = Σ_i  0.5^(i/H) · 1[n ∈ draw_i]

src/lib/engine-core.ts (HALF_LIVES = [8, 26, 78])

5. Boost de co-ocorrência PMI

Que números aparecem juntos mais vezes do que o acaso preveria?

  • Calculamos Pointwise Mutual Information: PMI(a,b) = log [P(a,b) / (P(a)·P(b))]. PMI positivo = o par aparece junto mais do que sob independência.
  • Por número candidato somamos o PMI com todos os números do sorteio mais recente. Isso dá um sinal 'segue o padrão' sem overfit: PMI é limitado e cortado a ±3.
score_PMI(n) = Σ_{m ∈ lastDraw}  clip(log[P(n,m) / (P(n)P(m))], ±3)

src/lib/engine-core.ts

6. Probabilidades de transição de Markov

A partir do último sorteio estimamos a probabilidade de transição para o próximo número.

  • Construímos uma matriz de transição N×N T com T[a,b] = P(b em draw_t+1 | a em draw_t), estimada com suavização de Laplace.
  • Para a pontuação live tomamos a média de T[a, n] sobre todos os a do último sorteio. Números frios não ficam frios para sempre; este passo modela memória finita.

src/lib/engine-core.ts

7. Ensemble e pesos afinados

Os seis sinais são fundidos via agregação ponderada de postos.

  • Cada sinal é convertido em percentis de posto [0, 1]. Depois combinado linearmente com pesos w = (w_bayes, w_ema1, w_ema2, w_ema3, w_pmi, w_markov). Uniforme por defeito; afinado por lotaria via grid-search + validação de ROI.
  • A agregação de postos é robusta a diferenças de escala entre sinais e evita que uma pontuação atípica domine o ensemble.
score(n) = Σ_s  w_s · rank_s(n) / N

src/lib/engine-core.ts · src/lib/engine-tuning.functions.ts

8. Meta-learner (regressão logística, 12 features)

Uma logreg por lotaria aprende a combinação não-linear ótima dos sinais do motor.

  • Vetor de features (12 dim): os 6 postos do motor + interações (EMA1·PMI, Bayes·Markov, EMA3·Bayes) + recência + hot streak (aparições nos últimos 10) + cold streak (ausências consecutivas).
  • Treino: logreg regularizada L2 com SGD sobre todo o histórico. Perda = log-loss sobre o rótulo '1 se o número apareceu no sorteio seguinte'. Retrocompatível: modelos antigos de 9 dim continuam a funcionar.
P(n no próximo sorteio) = σ(w · features(n) + b)

src/lib/meta-learner.ts

9. Gradient Boosted Decision Stumps

Segundo meta-learner que capta interações não-lineares sem rede neural.

  • Mini-clone do LightGBM: decision stumps iterativos sobre os resíduos. Cada stump escolhe 1 feature + threshold que reduz a perda ao máximo; adicionamos lr · stump.output à predição atual.
  • A saída é serializável em JSON e é guardada ao lado da logreg em engine_config.meta_weights.gbm. O blender empilhado combina os dois.

src/lib/gbm.ts

10. Blender de stacking out-of-fold

Logreg + GBM são combinados sem fuga de dados.

  • Dividimos o histórico em 5 folds estratificados. Por fold treinamos logreg + GBM em 4 folds e prevemos no fold retido. Essas predições OOF tornam-se as entradas de uma segunda camada meta-logreg que aprende a ponderação ótima.
  • Resultado: probabilidades calibráveis sem que o meta-learner reveja os seus próprios dados de treino.

src/lib/advanced-stats-v3.ts · src/lib/nested-cv.ts

11. Calibração isotónica e de Platt

As probabilidades brutas do modelo são monotonizadas para serem verdadeiramente probabilidades.

  • Platt scaling ajusta um sigmoide de 1 parâmetro sobre as pontuações brutas em dados de validação. A regressão isotónica (Pool-Adjacent-Violators) é uma versão não-paramétrica que apenas impõe monotonia.
  • Medimos o Expected Calibration Error (ECE) nas predições out-of-fold; o calibrador com menor ECE vai para produção.

src/lib/advanced-stats-v2.ts · src/lib/advanced-stats-v3.ts

12. Gerador de bilhetes anti-clustering

Os bilhetes candidatos são amostrados, estruturas más rejeitadas.

  • Sorteamos números proporcionalmente à pontuação do ensemble (softmax com temperatura τ afinada por lotaria). Cada candidato é validado:
  • • máx 3 da mesma década (anti-clustering),
  • • soma dentro da banda IQR histórica (sem bilhetes só baixos ou só altos),
  • • split de paridade dentro da distribuição empírica,
  • • sem sequência aritmética de ≥4 números consecutivos.
  • Candidatos rejeitados são reamostrados até termos N bilhetes válidos.

src/lib/engine-core.ts (generateAntiClusterTickets)

13. Seleção greedy submodular de portefólio

Entre milhares de candidatos escolhemos K bilhetes que juntos cobrem o máximo.

  • Problema: escolher K bilhetes que maximizem a soma de P(número sorteado) entre os bilhetes selecionados, com retornos decrescentes para sobreposição.
  • Funções submodulares trazem uma garantia de otimalidade de 1 − 1/e ≈ 63 % para a solução greedy. Por iteração escolhemos o bilhete com o maior ganho marginal e aplicamos fator 0.4 aos números já cobertos.
f(S ∪ {t}) − f(S) = Σ_{n ∈ t}  remain[n] · (½ se bónus)

src/lib/portfolio-optimizer.ts

14. Portefólio Markowitz de mínima variância

Além da cobertura minimizamos a correlação mútua entre bilhetes.

  • Correlação entre bilhetes i e j ≈ |overlap| / √(|t_i|·|t_j|). Greedy: escolher sempre o bilhete com maior EV menos λ · Σ corr(atual, escolhidos).
  • A aversão ao risco λ é um parâmetro afinável (defeito 1.2). λ mais alto = mais diversificação, menor pontuação esperada por bilhete mas menor variância do pagamento total do portefólio.
util(t) = EV(t) − λ · Σ_{j ∈ picked}  overlap(t, j)

src/lib/markowitz.ts

15. Correção de popularidade de jackpot partilhado

Um acerto numa combinação 'popular' é partilhado com mais vencedores.

  • popularityScore() conta: % de números ≤ 31 (aniversários), % na metade inferior, sequências consecutivas ≥3, progressões aritméticas, todos com o mesmo dígito final, cruzes/diagonais no boletim.
  • Com base nisso estimamos o número de co-vencedores e aplicamos adjustJackpotForSharing(): o EV no passo de gating usa o pagamento esperado após partilha, não o jackpot bruto.

src/lib/popularity.ts

16. EV gating ciente do jackpot

Aconselhar 'jogar' apenas quando o valor esperado é positivo.

  • EV = Σ_tier P(tier) · payout(tier) − ticketCost. P(tier) é exato a partir de odds combinatórios (coeficientes binomiais por fórmula de lotaria). Payout(tier) vem de PRIZE_TIERS — para a classe jackpot substituído pelo jackpot atual (após partilha por popularidade).
  • Também calculamos o break-even jackpot: o valor onde EV = 0. Abaixo disso, a UI mostra '⏸ saltar'.
  • O critério de Kelly determina o tamanho opcional da aposta para assinantes que planeiam várias semanas.
EV = Σ_t  P(t) · payout(t) − cost   |   break-even = (cost − Σ_{t≠jp} P(t)·payout(t)) / P(jp)

src/lib/ev-gating.ts

17. Deteção de regime (CUSUM + HMM 2 estados + filtro de partículas)

Detetar se o próprio gerador de sorteios se deslocou.

  • CUSUM segue por número um desvio cumulativo da frequência esperada e alarma ao ultrapassar o limiar h.
  • Um HMM de 2 estados (hot/cold) é treinado com Baum-Welch sobre a série temporal de frequência; transições são descodificadas por Viterbi.
  • Um filtro de partículas Sequential Monte Carlo mantém 200 partículas sobre o estado oculto de regime e dá uma probabilidade suave por sorteio.
  • Em mudança de regime a EMA curta recebe temporariamente mais peso (adaptação online).

src/lib/advanced-stats-v2.ts · src/lib/advanced-stats-v3.ts

18. Extensões estatísticas de nível 3

Conformal prediction, modelo de gap binomial negativo, cópulas, Shapley e mais.

  • • Split-conformal prediction → banda sobre meta-probs com cobertura garantida.
  • • A posteriori Dirichlet-Multinomial sobre o sorteio completo (não só por número).
  • • Modelo de gap binomial negativo para sobredispersão entre aparições.
  • • Cópula gaussiana para dependências de pares que o PMI perde.
  • • Teste de permutação por sinal (label-shuffle) → p-valor para 'melhor que o aleatório'.
  • • Atribuição SHAP por bilhete (aproximação linear) → explica porque este bilhete foi escolhido.
  • • CVaR / Expected Shortfall sobre pagamentos do portefólio.
  • • Goodness-of-fit Anderson-Darling sobre uniformidade.

src/lib/advanced-stats-v2.ts · src/lib/advanced-stats-v3.ts

19. Auto-tuner: CV aninhada + grid-search

Um pg_cron semanal revê pesos do motor e meta-modelos por lotaria.

  • CV estratificada 5-fold externa → estimativa de ROI fora de amostra. CV interna → seleção de preset.
  • Grid-search sobre simplex de pesos 6-dim (ponderado BMA) + presets de meias-vidas (HALF_LIFE_GRID). Para cada config: simular K bilhetes por fold, pontuar com tiers de prémios, agregar ROI com IC bootstrap 95 %.
  • Um novo preset só é aceite se CI-low > ROI baseline (não um golpe de sorte).
  • Os resultados vão para engine_config (DB) e estão imediatamente live para todos os assinantes.

src/lib/engine-tuning.functions.ts · src/routes/api/public/hooks/auto-tune.ts

20. Bandido Thompson-sampling (seleção online de preset)

Entre auto-tunes, um bandido alterna live entre presets com base no ROI atual.

  • Por preset mantemos um a posteriori Beta(α, β): α = vitórias (ROI > 0), β = derrotas. Em cada escolha de produção amostramos de cada Beta e escolhemos a amostra mais alta.
  • As atualizações vêm do tracker: assim que um sorteio termina, os presets escolhidos somam +1 em α ou β.
  • Resultado: mesmo sem re-tuning completo o sistema converge online para o melhor preset.
pick = argmax_p  Beta(α_p, β_p).sample()

src/lib/bandit.ts

21. Backtest walk-forward

Cada estratégia é testada sem conhecimento do futuro (sem fuga).

  • A partir de MIN_HISTORY iteramos sorteio a sorteio. Por sorteio construímos o modelo APENAS a partir de sorteios anteriores, geramos N bilhetes e pontuamos contra o sorteio real.
  • Agregamos acertos por tier, ROI médio, P&L cumulativo e uma baseline aleatória de controlo. Uma estratégia só 'ganha' se a sua banda CI estiver acima do aleatório.

src/lib/backtest.functions.ts

22. Sistemas de wheeling (covering designs)

Garantia matemática: com M números corretos no pool, sempre um prémio Y-de-X.

  • Implementamos full wheels, key wheels e covering designs abreviados. Para cada (tamanho de pool, tamanho de bilhete, garantia) escolhemos o conjunto combinatoriamente ótimo.
  • O gerador de wheels combina com o otimizador de portefólio: candidatos são primeiro wheeled e depois escolhidos submodularmente.

src/lib/wheel.functions.ts

Honestamente

As loterias são e continuarão jogos de azar. Nenhuma análise pode prever um sorteio. O que o LotteryCortex faz: ajudá-lo a tomar melhores decisões sobre que combinações jogar, quando apostar mais e quando saltar uma semana.

Os sorteios de lotaria são desenhados para ser aleatórios. Nenhum algoritmo — aqui ou noutro sítio — pode prever o resultado. O que fazemos de forma mensurável: escolher melhores distribuições de números, evitar combinações populares (para partilhar menos quando ganhar) e aconselhar honestamente a saltar quando o valor esperado é negativo. O auto-tuner valida semanalmente que a nossa curva de ROI está significativamente acima do aleatório — se isso deixar de ser verdade, lê-lo-á aqui primeiro.

Porquê LotteryCortex?

LotteryCortex reúne estatísticas históricas, backtests e acompanhamento numa aplicação web. A análise não prevê sorteios nem aumenta as suas hipóteses de ganhar.

The information on this website is created in part with the help of artificial intelligence and may contain errors or omissions. It is provided for general informational purposes only and does not constitute professional advice. Independently verify important details and consult a qualified professional when necessary. To the extent permitted by applicable law, we accept no liability for loss or damage arising from the use of, or reliance on, this information. This does not affect statutory rights or liabilities that cannot legally be excluded.