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.
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?
A maioria das ferramentas de loteria tem mais de 10 anos, são só em inglês e feitas para desktop. LotteryCortex é moderna, mobile-first e orientada para a UE — com um motor de IA que aprende continuamente.