📚 Methodology & Documentation

Complete reference for every section of the Jackpot Pools Dashboard — data sources, formulas, thresholds and methods, section by section.

← Back to the dashboard

1 · What this is system overview

The Jackpot Tracker is a monitoring system for progressive jackpot pools across 10 Bulgarian online casino operators (8888.bg, alphawin.bg, betano.bg, betvam.bg, efbet.com, elitbet.bg, inbet.com, palmsbet.com, sesame.bg, winbet.bg). Every 30 minutes it fetches the current value of every jackpot level on every site, stores the time-series in SQLite, and derives analytics from it: growth rates, payout detection, win forecasting, cross-operator comparison and market replay.

Collector (cron, every 30 min)
   └─ per-site fetchers → level_snapshots (SQLite)
        └─ analysis layer (api/data.py, api/dashboard_data.py)
             └─ REST API (FastAPI, port 8765)
                  └─ interactive dashboard (Plotly)

Everything shown on the dashboard is computed from observed data — no operator publishes jackpot statistics, so all numbers are reconstructed from the snapshot time-series.

2 · Core concepts & shared formulas

These definitions are used everywhere in the system. They are the foundation for every section that follows.

2.1 · Jackpot levels (L1–L4)

Multi-level jackpots (typically EGT-style) have up to four pools; every tracked value is tagged with its level:

LevelNameMeaning
L1GrandThe top pool — the headline jackpot. Most analytics operate on L1.
L2MajorSecond pool — pays much more frequently (see L2 Win Machines).
L3MinorThird pool.
L4MiniSmallest pool.
L0Single jackpotSome providers expose one undivided pool (e.g. Fazi, NGT/Juicy) — stored as level 0.

2.2 · Payout (win) detection

Casinos don't publish payout events, so a payout is inferred: when a jackpot level suddenly drops in value between two consecutive snapshots, someone won. The canonical rule used across the entire system:

WIN  ⇔  value_now < value_prev × 0.95   AND   value_prev − value_now > €100

i.e. a drop of more than 5% AND more than €100 between consecutive fetches
(30-minute resolution). Payout amount = value_prev − value_now.

This rule appears in: win lists, the Wall of Fame, win markers on every chart, the payout diamonds in deep-dive charts, the Replay timeline, the Forecast model and the Model Scoreboard.

2.3 · Organic growth

Jackpots grow from player stakes, and drop when they pay out. To measure the organic growth rate (how fast a pool accumulates money), payouts must be excluded — otherwise drops would bias the trend down. Two complementary methods are used:

a) Drop-anchored OLS slope (default for per-pool growth, 168 h window)

Take the last 7 days of snapshots, find the last payout (rule 2.2) and regress only on the segment after it — the pool's current uninterrupted climb. Also skip feed glitches where the next value jumps >10× and by >€100,000 (a common scraping artifact). Ordinary least squares:
growth = slope × 3600        [€/hour]
slope = Σ(xᵢ−x̄)(yᵢ−ȳ) / Σ(xᵢ−x̄)²   (x = seconds since segment start, y = € value)

b) Cumulative-positive-delta slope (default for site ranking & WoW, 72 h / 7-day windows)

Walk the snapshots and sum only positive deltas (payouts contribute zero), then fit an OLS line through the cumulative curve:
cum(t) = Σ δᵢ   where δᵢ = max(0, valueᵢ − valueᵢ₋₁)    (payout drops skipped, not subtracted)
growth = slope of cum(t), in €/hour

Both methods require a minimum number of points (typically 10 snapshots ≈ 5 h of data); pools without enough data show no growth or are skipped.

Why €/hour? A pool growing €50/h adds €1,200/day — directly comparable across pools of very different sizes, and it's the rate the operators themselves pay into the pool.

2.4 · ATH, % of record, and payout threshold

  • ATH (all-time high) — the largest payout ever recorded for a pool/level (top_win_amount).
  • % of record — current_value / ATH × 100; how close a pool is to its historical ceiling.
  • Payout threshold — statistics of what % of ATH the pool was at when past payouts happened: mean μ and standard deviation σ per pool. A pool that historically pays at ~85% of its record has threshold μ = 85%. If no ATH data exists, absolute € payout values are used instead.

2.5 · Canonical pools & category mapping

The same physical jackpot family (e.g. Bell Link) appears on many operators under slightly different titles and internal IDs. category_mapping.json maps every (site, title) pair to a canonical category — this is what powers all cross-site comparison, the "Big 3" (Bell Link, Jackpot Cards, Clover Chance) aggregations and the market totals. Pools whose titles can't be mapped appear under their raw title and cannot be compared across sites.

2.6 · Shared-jackpot deduplication

"Gods and Kings Link" mirrors Bell Link 1:1 on inbet/winbet — its values and wins are a duplicate feed and are excluded/blanked wherever wins are aggregated, so no payout is double-counted.

2.7 · Time zone

Snapshots are stored in UTC. All "activity" analytics (daily growth, heatmaps, When Bulgaria Plays uses UTC hours) that reference local days use Sofia time (UTC+3), so "Tuesday" means a Bulgarian Tuesday. The server itself computes in UTC.

3 · Data collection the raw feed

PropertyValue
CadenceEvery 30 minutes (cron) — every row of every chart has this base resolution
MethodPer-site fetchers: public/hidden JSON APIs, XHR interception via headless Chromium (Playwright), or WebSockets (8888 Juicy/NGT)
RetryUp to 5 attempts per site, exponential backoff (2n + jitter)
Quality validationPools present in ≥3 of the last 5 runs must appear, else the site is re-fetched (up to 2 retries) before a warning is recorded
RunsEach cycle is a fetch_run with status success / partial (some sites failed) / failed; per-site errors are parsed into the run summary
StorageSQLite (WAL): sites, pool_instances, pool_categories, level_snapshots (the time-series), fetch_runs
Some charts use only pools from the latest successful run (with a per-site fallback to that site's own latest run) so a single broken fetcher doesn't distort cross-site comparisons.

4 · Dashboard tab overview + risk

4.1 · Top stat cards

Live aggregates from the latest fetch: total market value (Σ of every pool's L1, falling back to its single level for L0 pools), pools tracked, sites online, wins detected, and tracking timespan (first → latest fetch run).

4.2 · Major Pools — bar charts

Current L1 values of the top 3 cross-site pool categories (Bell Link, Jackpot Cards, Clover Chance), one bar per operator. The y-axis is logarithmic because pools span orders of magnitude (a Mini-adjacent site value of €30k vs a record Bell Link at €2M+ would flatten a linear axis). Click any bar's value to open the deep-dive.

4.3 · Risk Dashboard

Pools ordered by statistical proximity to payout, combining: % of record, days since last payout, organic growth and market value concentration. It is the "watch-list" view of the forecast model — same risk levels as Next to Drop.

5 · Aggregated tab cross-site comparison

5.1 · Cross-Site Comparison table

The central matrix: one row per canonical pool (via the category mapping, section 2.5), one column per operator. Cells show the current L1 value, colour-coded by magnitude. Metadata per row:

  • Coverage — how many operators carry this jackpot (out of 10).
  • Max L1 — the highest value across operators at this moment.
  • Growth — Σ of per-site organic growth slopes (€/h, method 2.3a, 168 h window).
  • Wins — per-site win count and most recent payout (from provider metadata + drop detection).

Rows are sorted by total growth, then coverage. Every value is clickable → deep-dive.

5.2 · Latest Wins

All payout events (rule 2.2) plus provider-reported wins, newest first, filterable by level and amount range. Dates before 2000-01-01 are treated as missing (some providers report epoch-zero placeholders like 0001-01-01).

6 · Highlights tab WoW + records

6.1 · Week-over-Week growth

Each pool's organic growth this week vs the previous week, both computed with the same method (2.3b): two 7-day windows ending "now", cumulative positive deltas, payout drops excluded, OLS slope in €/h.

this_week  = slope over [now − 7d, now)
prev_week  = slope over [now − 14d, now − 7d)
change     = this − prev            [€/h]
change %   = (this − prev) / prev × 100

The card list shows the top 7 pools by combined growth; if fewer than 15 cards are available the remainder is padded from per-site pool growth (each marked with its previous-week slope for the change %). The badge shows the week-over-week direction of the leader.

6.2 · Drops (payout counts)

Per pool: number of detected payouts (rule 2.2) this week vs last week — a proxy for win frequency. High drop counts indicate either very active player bases or volatile (fast-pay) pools. Shows top 3 by volume plus bottom 2.

6.3 · All-Time Record Payouts — Wall of Fame

The highest payout ever recorded per (canonical pool × operator), ranked. The stat cards show: biggest tracked payout overall, pools with recorded records, wins in the current feed, and recent wins ≥ €100K. Click a jackpot name for its deep-dive.

7 · Per Site tab operator panels

One panel per operator (chips with the operator's colour dot at the top). Each panel contains:

7.1 · Top Pools by Value / by Growth

The 5 highest L1 values and the 5 fastest organic growth rates (€/h, method 2.3a, 168 h window) among that operator's pools. Chips are clickable → deep-dive.

7.2 · Daily growth bar charts (Big 3)

For Bell Link, Jackpot Cards and Clover Chance: one bar per day = that day's organic growth in €/h. A day is a Sofia local day (UTC+3, midnight-to-midnight). The orange markers show the previous 4-week average for the same weekday — so a tall bar with a low average is an unusual day. Red circles mark detected payouts on that day (rule 2.2). Rolling last 7 days.

day rate = Σ(positive deltas that day) / hours elapsed in that day's snapshots
avg      = mean of the same weekday's rates over the prior ≤4 weeks

7.3 · Hourly growth heatmaps

Below each bar chart: a 7-day × 24-hour matrix (rolling week, Sofia hours). Cell colour = organic €/h accumulated in that hour bin; green = growth, red = negative movement (never organic — always a payout or feed artifact). Each interval's rate is credited to the hour(s) it spans; payout drops reset the baseline without contributing.

7.4 · Pool cards grid

Every pool the operator carries, sorted by growth, with value and €/h. Any card is clickable → deep-dive.

8 · Forecasts tab the predictive layer

The only tab that makes statements about the future. Everything here is validated daily against real payouts by the Model Scoreboard (8.2) — the model grades itself.

8.1 · Next to Drop win probability forecast

Pools ranked by statistical proximity to their next payout. Per pool, the model computes:

  1. Payout threshold (section 2.4): μ, σ of the % of ATH at which this pool historically paid (or absolute € if no ATH). Pools with no observed payouts yet have risk_level = unknown and no forecast.
  2. Distance: remaining = threshold_value − current_value, in € and %.
  3. ETA: eta_days = remaining / growth_rate using the pool's current organic growth (method 2.3a).
  4. Risk level, from the pool's own payout statistics:
    current %ATH ≥ μ + σ  →  high
    current %ATH ≥ μ      →  elevated
    current %ATH ≥ μ − σ  →  moderate
    otherwise            →  low
  5. Win probability for 7/14/30-day windows — three tiers, best available used (field probability_method):

    Tier 1 — empirical (pool's own history)

    Survival estimate from the pool's own inter-payout intervals. If the pool has ≥3 intervals and ≥3 of them are longer than the current drought:
    P(payout within H days) = #(intervals with drought < iv ≤ drought + H) / #(intervals > drought)
    
    drought = days since this pool's last payout
    If the current drought already exceeds every historical interval, the pool is overdue_beyond_history and P = 98% for all windows. Probabilities clamped to [2%, 98%].

    Tier 2 — category (borrowed history)

    Pools already at/past their typical payout value but with too few own payouts (<3 intervals) use the same formula with the pooled intervals of every pool in the same jackpot category — e.g. a due Clover Chance instance borrows the payout cadence of all other Clover Chance instances.

    Tier 3 — heuristic (last resort)

    Only for pools with neither own nor category history: fixed anchors 60/80/95% when already past threshold; otherwise ETA-based:
    eta ≤ H:  P = max(0.10, 1 − (eta / H) × 0.5)      (50% at eta=H → 90% at eta≈H/10)
    eta > H:  P = min(cap, H / eta)                  cap: 15% (7d), 25% (14d), 40% (30d)
Sort order: risk level (high first), then remaining % to threshold. The columns "Typical payout at" and "Remaining" come straight from the pool's own payout history — the number shown is where this pool has historically paid.

8.2 · Model Scoreboard validated daily

The forecast model is not trusted blindly — it is measured. Every day (cron, 00:15) a snapshot of every pool's forecast (risk level, probabilities 7/14/30d, ETA, value) is appended to forecast_log.jsonl. When a prediction window fully elapses, the system checks whether that pool actually paid (rule 2.2) and scores the prediction:

  • Hit rate by risk level — of all pools marked high N days ago, what fraction paid within N days? A high-risk hit rate well above base rate is the model's core claim. Only fully-elapsed windows count (a 30-day prediction made 10 days ago is not yet gradeable).
  • Brier score — measures the honesty of the probabilities, not just correctness:
    Brier = mean over all scored predictions of (p − outcome)²
    
    outcome = 1 if the pool paid within the window, else 0
    p       = the probability the model logged for that window
    
    0 = perfect · 0.25 = a coin flip (always predicting 50%) · 1 = always maximally wrong
    Overconfidence is punished asymmetrically: predicting 90% and missing costs 0.81; predicting 90% and hitting costs 0.01. Any Brier below 0.25 beats chance.
  • Probability calibration (7d) — five buckets of 20%: of all predictions made at 60–80% confidence, what fraction actually paid within 7 days? If predicted ≈ actual in every bucket, the probabilities are trustworthy and can be read as true frequencies.
  • Confirmed calls — the model's trophy case: pools flagged high risk that paid within 7 days of the forecast, with the logged probability and the actual payout date.

8.3 · Hot Pools ≥80–85% of record + overdue

Pools near their all-time record that haven't paid recently, scored:

hot_score = % of record / 10 + min(days_since_win / 7, 5) + 3 · (never recorded a winner)

defaults: ≥ 85% of record AND ≥ 3 days since last payout
→ maximum score 10 (at ATH) + 5 (≥5 weeks overdue) + 3 = 18
Sorted by score; shared-jackpot duplicates removed (section 2.6).

8.4 · L2 Win Machines frequent payers

Level-2 (Major) pools with the highest observed payout frequency over the last 7 days (168 h). Win counts come from increments of the providers' own win_count counters (not drop detection), so these are reported wins:

win_rate_per_month = wins_in_window / days_spanned × 30
avg_interval_days   = days_spanned / wins
next-win window     = [last_win + interval, last_win + interval × 1.5]   (calendar dates)
Useful for spotting pools that pay small amounts very often — a different profile than the L1 "Next to Drop" list.

8.5 · When Bulgaria Plays 4-week activity clock

A proxy for aggregate player activity: when the market's jackpots grow fastest, Bulgarians are playing most. Uses the last 28 days of L1 snapshots; per-pool consecutive deltas are kept only if 0 < δ < €1M (positive only — payouts excluded, feed spikes capped); only pools with mean delta ≥ €50 contribute (filters out dead/near-inactive pools that would add noise). Aggregated into:

  • By weekday — Σ organic growth per day of week (Mon–Sun).
  • By hour — Σ organic growth per hour of day (00–23).

Practical use: promo/campaign timing — the bars show exactly when the player base is most active.

9 · Spotlight tab operator vs market

Pick any operator (chips) to see their competitive position:

  • Hero stats — pooled L1 value, active jackpot count, market share (site total / market total × 100), growth rank (from the 72 h ranking, section 11), organic growth €/h.
  • You vs the Market — for every shared jackpot: your value, the best competitor's value on the same jackpot, the diff % ((you − best)/best × 100), and your rank among operators carrying it. Green = you lead.
  • All-Time Records — the operator's biggest payouts ever, per jackpot.
  • Approaching Payout — that operator's slice of the forecast: pools nearest their typical payout value, with remaining %, ETA and risk (same model as 8.1).
  • Recent Wins — latest payouts detected for that operator (rule 2.2 + reported wins).

10 · Timeline tab market replay

Historical replay of the entire market (selectable 1–90 days, default 14):

  • Total market chart — one line per operator = Σ of that site's L1 pool values at each fetch run (downsampled to ≤600 points for rendering). Scrub the slider or press play to animate.
  • Market share stacked area — the same series normalised to 100%: each operator's share of the total tracked value over time.
  • Payout diamonds — every detected win (rule 2.2) pinned to the paying operator's line, never downsampled; the ticker below the slider lists them as the playhead passes.

11 · Growth ranking bar top of every page

Operators ranked by organic growth over the last 72 hours. Method: per pool, cumulative positive deltas (payouts excluded) over a 72 h window anchored at the latest fetch; OLS slope in €/h, negative slopes clamped to 0. Each site's score = sum of its top-5 fastest-growing pools — deliberately ignoring the tail of small/slow pools so one noisy jackpot can't dominate the ranking. Recomputed live on dashboard load.

12 · Winner ticker & Wall of Fame

Ticker (under the navbar): the latest 20 detected payouts, scrolling; pauses on hover. Wall of Fame — top 15 record payouts across all operators with the market-level record stats. Both use the shared payout rule (2.2) plus provider-reported wins, with epoch-zero dates filtered and shared-jackpot duplicates removed.

14 · REST API everything is scriptable

Every widget is fed by a JSON endpoint — the dashboard is a pure client. All data endpoints require the X-API-Key header (SHA-256-hashed keys, admin/client roles; every request is logged in the key-usage monitor). Interactive OpenAPI reference: /api/docs.

EndpointFeeds
GET /api/dashboardthe whole dashboard bundle (cross-site rows, weekly, heatmaps, wins, ranking)
GET /api/sites · /pools · /runs · /categoriesraw registry + time-series browsing
GET /api/growth/top · /sites · /dailygrowth analytics (methods 2.3)
GET /api/wins/latest · /dropspayout events (rule 2.2)
GET /api/predict/l1-forecast · /hot-pools · /l2-statsthe forecast layer (8.1–8.4)
GET /api/analysis/pool/{id} · /market · /highlights · /big-pools · /replay · /growth-patterns · /forecast-scoreanalysis layer (13, 8.2, 10…)

15 · Caveats & limitations honest disclaimers

  • Payout detection is inference. A >5% + >€100 drop is almost always a payout, but could occasionally be a provider-side reset or manual adjustment. Small payouts (<5% or ≤€100 on large pools) are invisible at 30-minute resolution.
  • Forecast ≠ certainty. Jackpot triggers are random (or provider-controlled); probabilities describe observed payout frequency, not a mechanism. The Model Scoreboard exists precisely to quantify how good these estimates are.
  • ATH is "highest observed" — a pool can always exceed its record; thresholds are living statistics that shift as history grows.
  • Feed glitches are filtered (10×/€100k spike rule) but not perfectly; any single-day anomaly deserves a second look at the raw history chart.
  • Uncategorized pools (rare/new jackpots) appear under raw titles, cannot be compared cross-site, and fall back to the heuristic probability tier until they accumulate payout history.
  • Heuristic tier. Pools with <3 own payouts and no category history still use hand-set anchors (60/80/95% when due); the probability_method field always discloses which tier produced a number.

Jackpot Tracker · methodology revision 26.09.03 · for informational purposes only.