# nhannguyenhcm95/lotto-quant-lab architecture

> Architecture diagram of the GitHub repository nhannguyenhcm95/lotto-quant-lab, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-10). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nhannguyenhcm95/lotto-quant-lab
- Repository: https://github.com/nhannguyenhcm95/lotto-quant-lab

## Overview

LOTTO-QUANT LAB is a browser-based lottery statistics and backtesting application for southern Vietnam lottery draws and Vietlott games. Its principal workflow selects a game or station, loads and normalizes draw history, runs independent quantitative models, combines their rankings, and presents analysis in the UI. A separate walk-forward backtest evaluates predictions against later draws while guarding against lookahead bias. The README documents live-source crawling and visualizations; sampled code supports the normalizer and several model details, but not every runtime connection, so those links are cited to the README where applicable.

Main entry points: [`xo-so/js/algorithms/ensemble.js`](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/ensemble.js) (Ensemble Ranker), [`xo-so/js/algorithms/input-normalizer.js`](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/input-normalizer.js) (Input Normalizer), [`xo-so/js/app.js`](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/app.js) (Application), [`xo-so/js/data-service.js`](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/data-service.js) (History Service)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_data["Draw Data"]
  node_crawl_vietlott["Vietlott Crawler<br/>[crawl-vietlott.js]"]
  node_crawl_xsmn["XSMN Crawler<br/>[crawl-xsmn.js]"]
  node_data_service["History Service<br/>[data-service.js]"]
  node_config["Game Config<br/>[config.js]"]
end

subgraph group_models["Quantitative Analysis"]
  node_normalizer["Input Normalizer"]
  node_poisson["Poisson Model<br/>[poisson.js]"]
  node_markov["Markov Model<br/>[markov.js]"]
  node_monte_carlo["Monte Carlo<br/>[monte-carlo.js]"]
  node_frequency_gap["Frequency Gap<br/>[frequency-gap.js]"]
  node_moving_average["Moving Average<br/>[moving-average.js]"]
  node_association["Association Rules"]
  node_clustering["K-Means Clustering<br/>[clustering.js]"]
  node_ensemble["Ensemble Ranker<br/>[ensemble.js]"]
end

subgraph group_validation["Backtesting"]
  node_backtest["Backtest Engine<br/>[backtest-engine.js]"]
  node_walk_forward["Walk-Forward Runner"]
end

subgraph group_presentation["Application UI"]
  node_app["Application<br/>[app.js]"]
  node_ui["UI Controller<br/>[ui-controller.js]"]
  node_charts["Chartist SVG<br/>[chartist.umd.js]"]
end

node_researcher(("Researcher"))
node_minhngoc["Minh Ngọc"]

node_minhngoc -->|"provides draws"| node_crawl_vietlott
node_minhngoc -->|"provides draws"| node_crawl_xsmn
node_crawl_vietlott -->|"supplies history"| node_data_service
node_crawl_xsmn -->|"supplies history"| node_data_service
node_config -->|"configures games"| node_data_service
node_researcher -->|"selects game"| node_app
node_app -->|"loads history"| node_data_service
node_app -->|"requests analysis"| node_ensemble
node_app -->|"requests backtest"| node_backtest
node_poisson -->|"normalizes history"| node_normalizer
node_markov -->|"normalizes history"| node_normalizer
node_monte_carlo -->|"normalizes history"| node_normalizer
node_frequency_gap -->|"reads draw events"| node_normalizer
node_moving_average -->|"normalizes history"| node_normalizer
node_association -->|"normalizes history"| node_normalizer
node_clustering -->|"reads draw events"| node_normalizer
node_ensemble -->|"runs model"| node_poisson
node_ensemble -->|"runs model"| node_markov
node_ensemble -->|"runs model"| node_monte_carlo
node_ensemble -->|"runs model"| node_frequency_gap
node_ensemble -->|"runs model"| node_moving_average
node_ensemble -->|"runs model"| node_association
node_ensemble -->|"runs model"| node_clustering
node_backtest -->|"canonicalizes results"| node_normalizer
node_walk_forward -->|"runs evaluation"| node_backtest
node_walk_forward -->|"evaluates models"| node_ensemble
node_app -->|"updates display"| node_ui
node_ui -->|"renders charts"| node_charts

click node_crawl_vietlott "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/netlify/functions/crawl-vietlott.js"
click node_crawl_xsmn "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/netlify/functions/crawl-xsmn.js"
click node_data_service "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/data-service.js"
click node_config "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/config.js"
click node_normalizer "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/input-normalizer.js"
click node_poisson "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/poisson.js"
click node_markov "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/markov.js"
click node_monte_carlo "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/monte-carlo.js"
click node_frequency_gap "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/frequency-gap.js"
click node_moving_average "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/moving-average.js"
click node_association "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/association-rules.js"
click node_clustering "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/clustering.js"
click node_ensemble "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/ensemble.js"
click node_backtest "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/backtest-engine.js"
click node_walk_forward "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/scripts/run-walk-forward.js"
click node_app "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/app.js"
click node_ui "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/ui-controller.js"
click node_charts "https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/chartist.umd.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_crawl_vietlott,node_crawl_xsmn,node_data_service,node_config toneBlue
class node_normalizer,node_poisson,node_markov,node_monte_carlo,node_frequency_gap,node_moving_average,node_association,node_clustering,node_ensemble toneAmber
class node_backtest,node_walk_forward toneMint
class node_app,node_ui,node_charts toneRose
class node_researcher,node_minhngoc toneIndigo
```

## Components

### Draw Data

- [Vietlott Crawler](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/netlify/functions/crawl-vietlott.js): `xo-so/netlify/functions/crawl-vietlott.js`
- [XSMN Crawler](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/netlify/functions/crawl-xsmn.js): `xo-so/netlify/functions/crawl-xsmn.js`
- [History Service](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/data-service.js): `xo-so/js/data-service.js`
- [Game Config](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/config.js): `xo-so/js/config.js`

### Quantitative Analysis

- [Input Normalizer](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/input-normalizer.js): `xo-so/js/algorithms/input-normalizer.js`
- [Poisson Model](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/poisson.js): `xo-so/js/algorithms/poisson.js`
- [Markov Model](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/markov.js): `xo-so/js/algorithms/markov.js`
- [Monte Carlo](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/monte-carlo.js): `xo-so/js/algorithms/monte-carlo.js`
- [Frequency Gap](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/frequency-gap.js): `xo-so/js/algorithms/frequency-gap.js`
- [Moving Average](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/moving-average.js): `xo-so/js/algorithms/moving-average.js`
- [Association Rules](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/association-rules.js): `xo-so/js/algorithms/association-rules.js`
- [K-Means Clustering](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/clustering.js): `xo-so/js/algorithms/clustering.js`
- [Ensemble Ranker](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/algorithms/ensemble.js): `xo-so/js/algorithms/ensemble.js`

### Backtesting

- [Backtest Engine](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/backtest-engine.js): `xo-so/js/backtest-engine.js`
- [Walk-Forward Runner](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/scripts/run-walk-forward.js): `xo-so/scripts/run-walk-forward.js`

### Application UI

- [Application](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/app.js): `xo-so/js/app.js`
- [UI Controller](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/ui-controller.js): `xo-so/js/ui-controller.js`
- [Chartist SVG](https://github.com/nhannguyenhcm95/lotto-quant-lab/blob/main/xo-so/js/chartist.umd.js): `xo-so/js/chartist.umd.js`

### Other components

- **Researcher**
- **Minh Ngọc**

## Connections

- Minh Ngọc → Vietlott Crawler: provides draws
- Minh Ngọc → XSMN Crawler: provides draws
- Vietlott Crawler → History Service: supplies history
- XSMN Crawler → History Service: supplies history
- Game Config → History Service: configures games (evidence: `xo-so/js/data-service.js`)
- Researcher → Application: selects game
- Application → History Service: loads history (evidence: `xo-so/js/app.js`)
- Application → Ensemble Ranker: requests analysis (evidence: `xo-so/js/app.js`)
- Application → Backtest Engine: requests backtest (evidence: `xo-so/js/app.js`)
- Poisson Model → Input Normalizer: normalizes history (evidence: `xo-so/js/algorithms/poisson.js`)
- Markov Model → Input Normalizer: normalizes history (evidence: `xo-so/js/algorithms/markov.js`)
- Monte Carlo → Input Normalizer: normalizes history (evidence: `xo-so/js/algorithms/monte-carlo.js`)
- Frequency Gap → Input Normalizer: reads draw events (evidence: `xo-so/js/algorithms/frequency-gap.js`)
- Moving Average → Input Normalizer: normalizes history (evidence: `xo-so/js/algorithms/moving-average.js`)
- Association Rules → Input Normalizer: normalizes history (evidence: `xo-so/js/algorithms/association-rules.js`)
- K-Means Clustering → Input Normalizer: reads draw events (evidence: `xo-so/js/algorithms/clustering.js`)
- Ensemble Ranker → Poisson Model: runs model (evidence: `xo-so/js/algorithms/ensemble.js`)
- Ensemble Ranker → Markov Model: runs model (evidence: `xo-so/js/algorithms/ensemble.js`)
- Ensemble Ranker → Monte Carlo: runs model (evidence: `xo-so/js/algorithms/ensemble.js`)
- Ensemble Ranker → Frequency Gap: runs model (evidence: `xo-so/js/algorithms/ensemble.js`)
- Ensemble Ranker → Moving Average: runs model (evidence: `xo-so/js/algorithms/ensemble.js`)
- Ensemble Ranker → Association Rules: runs model (evidence: `xo-so/js/algorithms/ensemble.js`)
- Ensemble Ranker → K-Means Clustering: runs model (evidence: `xo-so/js/algorithms/ensemble.js`)
- Backtest Engine → Input Normalizer: canonicalizes results (evidence: `xo-so/js/backtest-engine.js`)
- Walk-Forward Runner → Backtest Engine: runs evaluation (evidence: `xo-so/scripts/run-walk-forward.js`)
- Walk-Forward Runner → Ensemble Ranker: evaluates models (evidence: `xo-so/scripts/run-walk-forward.js`)
- Application → UI Controller: updates display
- UI Controller → Chartist SVG: renders charts
