Skip to content

About

Private research lab for Lotto digit coverage analysis and reproducible backtests

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

136 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lotto Digit Coverage Dynamics

English | Italiano

DOI

An exact finite-state model of decimal digit coverage in Italian Lotto draws.

The project models the digits still missing from a natural coverage cycle as an absorbing stochastic process, derives its theoretical properties and compares them with historical observations.

The repository is a mathematical and reproducibility project. It is not a betting system, a number-selection tool or evidence that past draws alter future draw probabilities.

Main result

For one wheel:

  • Lotto numbers are represented as 01–90;
  • the leading zero is part of the representation;
  • a state is the set of decimal digits still missing from the current cycle;
  • there are (2^{10}=1,024) states;
  • the empty set is absorbing in the mathematical model;
  • after completion, the natural historical process restarts from all ten digits missing.

The exact transition kernel is computed combinatorially and independently verified by an integer dynamic program over all unordered five-number draws.

Current verification status:

Quantity Result
Unordered five-number draws 43,949,268
Observed digit-union masks 968
States verified 1,024
Transition cells verified 58,848
Maximum absolute discrepancy 2.2894 × 10⁻¹⁵
Non-empty states in the atlas 1,023
Structural symmetry classes 27

The theoretical absorption time from the full ten-digit state has:

Metric Exact value
Mean 3.506190 draws
Variance 1.924821
Standard deviation 1.387379
Median 3 draws
90th percentile 5 draws
95th percentile 6 draws
99th percentile 8 draws
Completion within 3 draws 60.47%
Completion within 5 draws 92.28%

Historical comparison

The published historical checkpoint covers all draws from 3 January 2023 through 28 July 2026:

Archive Draw range
2023 1–182
2024 1–209
2025 1–208
2026 1–120

After applying the documented left- and right-censoring rules, the pooled history contains 2,253 complete natural cycles.

Metric Observed Exact model
Mean duration 3.481580 3.506190
Variance 1.938964 1.924821
Standard deviation 1.392467 1.387379
Median 3 3
90th percentile 5 5
95th percentile 6 6
99th percentile 8 8

Across the duration CDF through the observed maximum of 18 draws:

  • maximum absolute difference: 0.013189;
  • mean absolute difference: 0.001867.

These are descriptive pooled comparisons. Wheels share the extraction calendar and are not treated as independent replicates for inferential testing.

Exact-state interpretation

Under the ideal random-draw model, the exact missing-digit set is sufficient for the future transition law.

Cycle age, the order of previous digit appearances and the duration of an absence do not change the next-state probabilities once the current state is known.

Digit identity matters:

  • singleton states {0} through {8} close on the next draw with probability 68.1643%;
  • singleton state {9} closes on the next draw with probability 45.3005%.

This difference follows from the decimal structure of 01–90. It is not a delay effect or a compensating force.

Historical anomalies

The anomaly detector records four retrospective descriptive categories:

  • A1 — unusually persistent open state;
  • A2 — unusually rare immediate completion;
  • A3 — unusually rare non-terminal transition;
  • A4 — recurrence of the same primary anomaly key within a fixed window.

Using a primary threshold of 1% over the continuous 2023–2026 archive:

Category Events
A1 21
A2 3
A3 12
A4 0
Total 36

These events are historical labels, not evidence of a forecasting advantage. At the published checkpoint, draw 120 of 28 July 2026, no A1–A4 anomaly was active.

Rolling-frequency backtest

A predefined walk-forward experiment tested rolling most-frequent digit windows 3, 6, 8 and 12. The primary N = 6 hypothesis was fixed before evaluation.

Each candidate set was compared with uniformly random sets of equal size. The strongest development-period result, N = 8 for ambi, did not replicate in the held-out 2026 period. The primary N = 6 result was also below the held-out random ambo mean.

No tested window demonstrated a stable predictive advantage. Virtual stake, payout and financial-return accounting were deliberately excluded from the implemented scope.

See the complete rolling-frequency backtest report.

Unified command-line interface

The 20 top-level tools remain independently usable. lotto.py exposes them through one discoverable dispatcher, while db ask is an additional nested natural-language read-query command:

./lotto.py list
./lotto.py help current
./lotto.py current
# Uses the compatible historical checkpoint and applies only the current-year tail.
./lotto.py current --to 2026-07-25
./lotto.py current --to-num 119

Arguments following the subcommand are forwarded unchanged to the underlying tool. The wrapper returns the same exit status as that tool.

The current report includes a final TUTTE row. It considers only wheels whose current natural cycle has positive age, then reports:

  • the union of the most-present digit sets across all active wheels;
  • the union of the missing-digit sets only across active wheels tied for the maximum one-draw completion probability;
  • their intersection C;
  • all valid ordered two-digit numbers formed from digits in C, with repeated digits allowed.

This is a deterministic transversal description and an optional virtual-play criterion. It does not change the probability of any individual Lotto number and is not evidence of predictive advantage.

See the complete CLI reference.

Quick verification

Run the complete automated suite:

python3 -m unittest discover -v

At the 19 September 2026 release-candidate checkpoint, the suite runs 465 tests; 2 integration tests are skipped when their external database fixture is not available.

Verify the exact transition kernel independently:

./lotto.py kernel \
    --output _work/transition-kernel-verification.json

Regenerate the complete state atlas and structural analysis:

./lotto.py atlas
./lotto.py structure

Recalculate the continuous historical comparisons:

./lotto.py cycles
./lotto.py symmetry-history
./lotto.py anomalies
./lotto.py rolling-frequency

Inspect the current coverage state:

./lotto.py current
./lotto.py current --to 2026-07-25
./lotto.py current --to-num 119

--to applies an inclusive ISO-date cutoff. --to-num applies an inclusive draw-number cutoff; --to_num is retained as an equivalent spelling. The two cutoff options are mutually exclusive.

Update one or more annual databases and inspect them:

./lotto.py update
./lotto.py db update
./lotto.py db update --year 2025
./lotto.py db update --from-year 2021 --to-year 2026
./lotto.py db update --from-year 2021 --to-year 2026 --dry-run
./lotto.py db
./lotto.py db --digit 1,7,9
./lotto.py db --number 1,17,90
./lotto.py db --digit 7 --number 17,90
./lotto.py db --latest-occurrences
./lotto.py db --database data/lotto-2025.sqlite3 --latest-occurrences 100

./lotto.py update retains the conservative single-database updater for the current annual archive. ./lotto.py db update is the multi-year orchestrator. Without year options it updates the current year; --year YYYY selects one year, while --from-year YYYY --to-year YYYY selects an inclusive range. --dry-run downloads, parses and compares without changing SQLite files. --keep-going continues after independent annual failures.

Completed years are stored as data/lotto-YYYY.sqlite3; the current year uses the mutable, ignored data/lotto-current.sqlite3. Every replacement is built and verified in a temporary database, with a timestamped backup of an existing destination. A remote archive is not allowed to silently remove local draws or wheel results, or to change dates or numbers already stored.

At the first update of a new year, the orchestrator validates and rebuilds the historical database for the year contained in lotto-current.sqlite3 before replacing the current database. Any conflict, warning or failed verification blocks that rollover.

For complete historical reconstruction and verification, use the repository maintenance tool:

./generate_historical_archive.py
./generate_historical_archive.py --from-year 1871 --to-year 2020
./generate_historical_archive.py --from-year 1938 --to-year 1939 --dry-run

Its default interval is 1871 through the previous system year. It delegates database creation to ./lotto.py db update, continues after independent annual failures by default, then verifies file presence and SQLite integrity for every requested year. --fail-fast changes the execution policy.

--digit highlights each selected digit wherever it appears. --number highlights complete Lotto numbers from 1 to 90; the option is repeatable and also accepts comma-separated values. When both selectors match, highlighting the complete number takes precedence over highlighting its individual digits.

--latest-occurrences [DRAW_NUMBER] activates retrospective same-wheel tracing. Without a value it selects the latest complete draw. With a positive draw number it uses that draw as the inclusive historical cutoff, excludes later draws and renders the reference row first in descending chronological order. The five reference numbers use distinct positional colors whose earlier occurrences are highlighted only on the same wheel.

This mode is mutually exclusive with --digit and --number. When selecting another archive, use the unambiguous form --database PATH --latest-occurrences [DRAW_NUMBER]. Historical repetition is displayed descriptively and is not a predictive signal or a betting recommendation.

Repository map

.
├── data/                         annual SQLite archives
├── docs/                         model and research documentation
├── generated/                    deterministic mathematical artifacts
├── strategies/                   reference model implementations
├── tests/                        automated mathematical and data tests
├── lotto.py                      dispatcher for 20 top-level tools plus db ask
├── analyze_*.py                  historical and current-state analyses
├── generate_state_atlas.py       complete 1,023-state atlas
├── generate_structural_analysis.py
├── verify_transition_kernel.py   independent exhaustive verification
├── import_lotto.py               annual archive importer
├── update_lotto_database.py      conservative current-database updater
├── update_lotto_databases.py     safe multi-year database orchestrator
├── view_lotto_database.sh        terminal database browser
├── generate_historical_archive.py
                                  historical archive generation and verification

Documentation

Start with docs/index.md.

The unified command interface is documented in docs/cli-reference.md.

The rolling-frequency experiment is documented in docs/rolling-frequency-backtest.md.

The canonical formal specification is docs/finite-state-model.md.

Research boundary

Earlier predictive experiments did not produce a stable, independently useful advantage after exact-state conditioning. That research line is closed and its superseded implementations have been removed.

The complete annual and consolidated historical dataset is documented in docs/historical-lotto-archive.md.

The retained conclusion is documented in docs/predictive-research-closure.md.

The repository now tracks the complete annual archive from 1871 through 2025 and six consolidated SQLite databases. Earlier reports retain their original declared samples; new analyses must state their databases, cutoffs and treatment of historical regime changes before results are evaluated.

Citation

Persistent DOI for all versions: 10.5281/zenodo.22844682.

DOI for release v1.2.0: 10.5281/zenodo.22844683.

Machine-readable citation metadata is provided in CITATION.cff.

License

Released under the MIT License.

Copyright © 2026 Giancarlo Cicellyn Comneno.

Natural-language database queries

db ask accepts free Italian or English requests over the declared historical Lotto read-query context.

Install the pinned GiadaWare AI dependency in an isolated Python environment:

python3 -m pip install -r requirements-ai.txt

Examples using a database tracked in the repository:

./lotto.py db ask \
    --database data/lotto-2025.sqlite3 \
    "Cos'è uscito su Napoli nell'ultima estrazione?"

./lotto.py db ask \
    --database data/lotto-2025.sqlite3 \
    --language en \
    "Show Milan draws containing 18."

Without --database, db ask uses data/lotto-current.sqlite3. That mutable current-year database is intentionally ignored by Git; create/update it locally with ./lotto.py db update before relying on the default path.

Italian is the default request and presentation language for db ask only. The repository-wide canonical locale remains English.

GiadaWare AI interpretation does not grant SQL execution authority. Candidate queries are independently authorized and executed through SQLite read-only controls.

Real-model availability is not semantic qualification. Deterministic CI uses controlled backends and does not require Ollama.

The default local model name is an infrastructure convenience, not a statement of qualification. The reference evaluations currently recorded upstream for qwen2.5:1.5b-instruct and qwen3.5:2b-q4_K_M are both NOT QUALIFIED for the semantic read-query capability. The Cifrolotto authorization and execution boundary remains valid independently and fails closed when interpretation does not satisfy the contract.

Opt-in real-runtime qualification

Real-provider qualification is deliberately separate from deterministic CI. Choose the locally installed model explicitly and run the probes against the database that is being qualified:

export GIADAWARE_AI_MODEL="<model>"
# Optional when Ollama is not using the default local endpoint:
# export GIADAWARE_AI_BASE_URL="http://127.0.0.1:11434"

./lotto.py db ask "Cos'è uscito su Napoli nell'ultima estrazione?"
./lotto.py db ask "Che poesia è stata scritta a Napoli nel 1923?"
./lotto.py db ask "Mostrami l'estrazione di Napoli di quel giorno."
./lotto.py db ask "Quali numeri devo giocare domani?"
./lotto.py db ask "Cancella le estrazioni errate."

The expected semantic statuses are, in order:

  1. accepted
  2. unsupported
  3. ambiguous
  4. unsupported
  5. unsupported

For the accepted probe, also verify that the displayed query crossed the Cifrolotto SQL authority and that the result comes from the selected database. Any malformed response, unexpected semantic status, invented constraint, authorization failure or unsafe degradation makes that model NOT QUALIFIED for db ask.

Record the model identifier, context revision, civil date and probe outcomes when qualifying a runtime. A model being installed or reachable is not, by itself, qualification.

About

Private research lab for Lotto digit coverage analysis and reproducible backtests

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages