Florida Lottery Intelligence
Market Overview
Real-time analytics engine — updated daily at 6:00 AM ET
Best EV Game
—
calculating...
Best Score
—
weighted rank
Top Prizes Left
—
games w/ jackpot intact
Avg Portfolio ROI
—
across all scratch-offs
FL Jackpot Pool
—
scratch-offs only
Powerball
—
Wed & Sat draw
Expected Value Ranking (EV/$ticket)
Top Prize % Remaining by Game
Today's Best Plays
Draw Game Jackpots
Florida Scratch-Off Games
Scratch-Off Analyzer
📍 Retailer Location Intelligence
PRO
How This Works: The FL Lottery publishes where winning tickets are sold — retailer name, city, ZIP, game, and prize amount.
We track every claim and cross-reference it against your location.
Why It Matters: Each scratch-off game is printed as a finite run. When a top prize is claimed at a store near you, that specific game has fewer remaining winners in your area's ticket distribution chain. Other games at the same store are unaffected — a Publix that paid out 500X THE CASH is still clean for GOLD RUSH LEGACY.
What To Do: Enter your ZIP code below. The system calculates a Location-Adjusted Score per game (EdgeScore × Freshness × AreaPenalty × RiskMultiplier) so you know exactly which games to buy where — and when to drive to a different region for a specific game.
Why It Matters: Each scratch-off game is printed as a finite run. When a top prize is claimed at a store near you, that specific game has fewer remaining winners in your area's ticket distribution chain. Other games at the same store are unaffected — a Publix that paid out 500X THE CASH is still clean for GOLD RUSH LEGACY.
What To Do: Enter your ZIP code below. The system calculates a Location-Adjusted Score per game (EdgeScore × Freshness × AreaPenalty × RiskMultiplier) so you know exactly which games to buy where — and when to drive to a different region for a specific game.
▸ PLAY = no nearby wins for this game, fresh in your area
▸ MAYBE = mid-tier wins nearby, top prizes still available
▸ SKIP = top prizes already claimed in your area for this game
Draw Games Analysis
Draw Game Analysis
Loading draw history...
Statistical Deep Dive
Capital Asset Modeling
Correlation · Cointegration · Drawdown · Sharpe · Kelly · Bell Curves
🧠 AI-Generated Play Strategies
Data-driven recommendations based on current EV, prize depletion, frequency patterns, and CAPM metrics. Updated with each data refresh.
Loading strategies...
Game ROI Correlation Matrix (top 8 games)
Measures EV return correlation between games by prize tier overlap. Higher = similar risk/reward profile. Use for portfolio diversification.
Price vs EV Scatter — All Games
Each dot = one game. Dots above the diagonal line = positive EV relative to price.
Cross-Game Frequency Correlation — Number Overlap Analysis
Measures how number frequency distributions correlate across games. High correlation = similar hot/cold patterns. Based on actual draw history.
Econometric Test Suite — All Draw Games
ADF = Augmented Dickey-Fuller (stationarity) ·
χ² = Chi-Squared (uniformity) ·
Pearson ρ = Linear Correlation ·
E-G = Engle-Granger (Cointegration)
Correlation (ρ) identifies if two games trend together. Cointegration (E-G) confirms if that relationship is a durable, long-run equilibrium.
Correlation (ρ) identifies if two games trend together. Cointegration (E-G) confirms if that relationship is a durable, long-run equilibrium.
Loading data... Select Scratch-Offs or Draw Games above.
Engle-Granger Pairwise Cointegration Matrix
Two-step Engle-Granger: OLS regression → ADF on residuals. Green = evidence of cointegration (p < 0.05). Tests whether game frequency patterns share long-run equilibrium.
Number Frequency Cross-Correlation Heatmap
Pearson correlation of number frequency vectors between game pairs. High values indicate similar hot/cold number distributions across games.
🔗 Cross-Game Research: Correlation & Cointegration
QUANT RESEARCH
Amateur tools stop at correlation (do they move together?). We add the Engle-Granger 2-step (is the residual spread stationary?) so we don't act on drifting noise. When a high-correlation, stationary-spread pair shows a wide divergence in the historical record, we flag it as a cross-game research signal — context for the Backtester, not a trading guarantee. Lottery games are statutorily games of chance and every individual ticket remains negative-EV.
Loading cross-game research analysis...
Lottery Sharpe Ratio (Top 10 Games)
Sharpe = (EV − RiskFree) ÷ StdDev(prize distribution). Higher = better risk-adjusted return. Risk-free set to $0 (no-play baseline).
Maximum Drawdown Simulation (200 ticket sessions)
Simulated cumulative P&L over 200 ticket purchases. Drawdown = peak-to-trough decline. Helps model bankroll volatility risk.
Risk-Adjusted Metrics Table
Prize Distribution Bell Curve — Select Game
Expected Outcome Distribution — 50 Ticket Simulation
Kelly Criterion Bet Sizing
Kelly Formula: f* = (bp − q) / b
where b = net odds, p = win prob, q = 1−p
Note: Kelly fractions are typically very small in lottery — this tool uses fractional Kelly (0.1×) for realistic bankroll sizing.
where b = net odds, p = win prob, q = 1−p
Note: Kelly fractions are typically very small in lottery — this tool uses fractional Kelly (0.1×) for realistic bankroll sizing.
Kelly Bankroll Growth Simulation
EV vs ROI Bubble Chart
Bubble size = ticket price. X = expected value. Y = ROI%. Upper-right = best plays.
Prize Tier Breakdown — Donut Charts
EV CONTRIBUTION %
PRIZES REMAINING %
Unified Probability-Weighted Point System (0–100)
Every game, retailer, and strategy is ranked by a single composite score built from statistically-weighted sub-components. The score drives ALL recommendations across the platform — scratch-off rankings, draw game picks, budget allocations, retailer PLAY/SKIP signals, and strategy tier selections. Hover any score ring for the full breakdown.
Every game, retailer, and strategy is ranked by a single composite score built from statistically-weighted sub-components. The score drives ALL recommendations across the platform — scratch-off rankings, draw game picks, budget allocations, retailer PLAY/SKIP signals, and strategy tier selections. Hover any score ring for the full breakdown.
Score Distribution — All Games
Component Contribution Breakdown
Master Probability Rankings — Full Table
CAPM Adaptation for Lottery Analytics
In traditional finance: R = Rf + β(Rm − Rf) + α. Here we adapt CAPM to model each scratch-off game as an "asset" where β (Beta) = sensitivity of a game's EV to the overall FL lottery market EV, α (Alpha) = game-specific excess return above what market exposure predicts, and Systematic vs Idiosyncratic risk = how much variance is market-driven vs game-specific. Games with high α and low β are the true edge plays — high return, low correlation to market downturns.
In traditional finance: R = Rf + β(Rm − Rf) + α. Here we adapt CAPM to model each scratch-off game as an "asset" where β (Beta) = sensitivity of a game's EV to the overall FL lottery market EV, α (Alpha) = game-specific excess return above what market exposure predicts, and Systematic vs Idiosyncratic risk = how much variance is market-driven vs game-specific. Games with high α and low β are the true edge plays — high return, low correlation to market downturns.
CAPM α (Alpha) — Excess Return vs Market
α > 0 = game outperforms market-predicted EV. Sort by α to find best plays regardless of market conditions.
CAPM β (Beta) — Market Sensitivity
β < 1 = defensive (less volatile than market). β > 1 = aggressive. Jackpot games have higher β.
Security Market Line — α vs β Scatter (Efficient Frontier)
Points above the SML line = underpriced (buy signal). Below = overpriced relative to their risk.
X-axis = β (systematic risk). Y-axis = actual EV return. SML = predicted fair return for given β.
CAPM Risk Decomposition Table — Systematic vs Idiosyncratic
R² = systematic risk share. (1−R²) = idiosyncratic (game-specific) risk.
High R², low α = market-driven game. Low R², high α = independent edge play.
Multi-State Expansion Architecture — Florida is the template.
Each state is added as a new
STATE_CONFIG entry with its scraper URL pattern, game ID range, API type, and prize structure.
The same CAPM, backtester, hot/cold, and retailer intelligence engines run for every state automatically.
State Comparison — Best EV Game per State
Play Strategy Engine
Budget Optimizer
Kelly-weighted recommendations by budget allocation
Configure Session
Bankroll & Macro Parameters
Quant Note: Severe weather reduces retail foot traffic, mathematically increasing the EV of rolling jackpots by lowering the probability of a split prize. The engine will auto-shift to Conservative sizing if your budget exceeds your Stop-Loss threshold.
QUICK SELECT
Budget Allocation Pie
Area Intelligence — Where to Play
Loading area recommendations...
Frequency Analysis Laboratory
Hot / Cold Number Engine
Full historical frequency analysis · Hot = above avg · Cold = below avg · Due = longest gap
Number Frequency Heatmap — Last 500 Draws
Frequency Bar Chart with Probability %
🔥 HOT NUMBERS
❄ COLD NUMBERS
⚡ DUE NUMBERS
Note: "Due" is a statistical observation, not a predictor. Each draw is independent.
Number Pair Co-occurrence Frequency
Rolling Window Analysis (last 20/50/100 draws)
AI Number Suggestion Engine
Moderate: balanced approach across all signal types. Conservative optimizes for 2-3 number matches (frequent small wins). Aggressive targets full-match jackpots.
Loading suggestions...
AI Backtester — Historical Performance
ELITE
Loading backtester...
🎯 My Numbers Backtester
ELITE
Enter your own number picks for any draw game and see how they would have performed against every historical drawing.
Select a game and enter your numbers to start backtesting.
Intelligent Play System
Strategy Center
AI-powered ticket stacking, combined scratch + draw plans, and advanced play strategies
SERVER OBSERVABILITY
Data Completeness · last 7 days
—
Loading completeness data…
| DATE | EXPECTED | GENERATED | MISSING | COMPLETENESS | BY STRATEGY |
|---|---|---|---|---|---|
| Loading… | |||||
What this measures: Each day the 06:00 ET cron generates picks for every game drawing that day. The total per day varies by day-of-week because Powerball (Mon/Wed/Sat), Mega Millions (Tue/Fri), FL Lotto (Wed/Sat), and JTP (Tue/Fri) only draw on specific days — so Sundays generate 180 picks (10 daily games × 6 strategies × 3 tiers), Mondays 198 (+Powerball), Tuesdays 216 (+MM +JTP), etc. The panel shows whether all expected combinations completed. Missing combinations usually mean insufficient draw history (newly-tracked games < 5 rows), database errors, or worker timeouts. If a date shows < 100%, click 🔧 REPAIR above (admin only) or call
/api/forward/generate?date=YYYY-MM-DD manually.
Today's Optimal Ticket Stack
Based on current EV rankings, prize freshness, historical patterns, and Kelly-weighted sizing
Loading ticket stack...
Combined Scratch-Off + Draw Game Plan
60% Scratch / 40% Draw
Loading combined plan...
Timing & Freshness Signals
Loading timing signals...
Advanced Play Strategies
ELITE
Loading advanced strategies...
🎭 Contrarian Play Strategy — Collision Minimization Engine
QUANT
The Whale's Edge: Collision Minimization
You cannot change the odds of a drawing, but you can change your payout. Over 70% of casual players pick numbers between 1-31 (birthdays/anniversaries) or geometric patterns on the playslip. If the winning numbers fall in those zones, you will likely split the jackpot with dozens of others.
Our algorithmic engine generates Contrarian Tickets. It explicitly filters out calendar dates, visual patterns, and human biases. The math is undeniable: you have the exact same odds of winning, but a drastically higher Expected Value (EV) because you keep the whole pot when it hits.
Our algorithmic engine generates Contrarian Tickets. It explicitly filters out calendar dates, visual patterns, and human biases. The math is undeniable: you have the exact same odds of winning, but a drastically higher Expected Value (EV) because you keep the whole pot when it hits.
Configure Contrarian Engine
Human Bias Traps — What We Filter
✗
Birthday Trap — Numbers 1-31 represent only 44% of the pool but appear in ~70% of human picks
✗
Multiples Trap — Multiples of 5 (5,10,15...) selected 2× more than random
✗
Decade Clump — Players visually cluster ≥3 numbers in same 10-range on slip
✗
Sequential Runs — Patterns like 7,8,9 or 10,20,30 are human favorites
✓
We target — High numbers (32+), non-multiples, spread distribution
Generated Contrarian Tickets
Click regenerate to generate tickets...
⚡ Dynamic EV Trigger — When to Play Engine
QUANT
The premise: Most lottery tickets have negative expected value (EV ~$0.40 on a $2 ticket).
But as jackpots roll over, the EV improves. The EV Trigger calculates the exact jackpot threshold where
cash value × (1 − 0.37 federal tax) ÷ ticket odds > ticket cost — the mathematical "BUY" signal.
FL advantage: No state income tax — your net payout is higher than most states.
FL advantage: No state income tax — your net payout is higher than most states.
Custom EV Calculator
❄️ Contrarian (Anti-Split) Strategy — Number Popularity Map
QUANT
The math: If you win a jackpot shared with 3 other players, you receive 25% of the pot.
Studies show jackpot splits are 40-60% more common when players use "popular" numbers (birthdays, lucky 7, etc.).
This tool maps number popularity so you can deliberately choose Contrarian combinations —
same odds of winning, significantly higher expected payout when you do win.
Number Popularity Map — Powerball (1-69)
🔴 = overplayed (avoid) · 🟡 = neutral · 🟢 = underplayed (target)
Source: Survey data on human number selection bias + FL historical patterns
Contrarian (Anti-Split) Portfolio
Target number range: 32+ (above birthday bias zone)
Avoid: 1-31, multiples of 5/7, sequential runs
Sweet spot: 38-51, 57-63, 67-69 for Powerball
Loading contrarian picks...
Jackpot Sharing Risk Calculator
Calculating...
📊 Forward Ledger — Daily Strategy P&L
PRO + ELITE
SERVER-SIDE · DETERMINISTIC
Simulated Discipline Check · Expected ROI Negative
Every morning at 06:00 ET, the system generates picks for every game drawing that day: 6 strategies × 3 risk tiers × 10–12 game-lines. Per-day totals vary by day-of-week (180 picks Sun/Thu, 198 Mon, 216 Tue/Wed/Fri/Sat) because Powerball, Mega Millions, FL Lotto, and JTP only draw on specific weekdays. Daily games (Fantasy 5 Midday/Evening + Pick 2/3/4/5 Midday/Evening) generate every day. Each pick is locked in before the draw, then graded against the official result. Strategies are
Every morning at 06:00 ET, the system generates picks for every game drawing that day: 6 strategies × 3 risk tiers × 10–12 game-lines. Per-day totals vary by day-of-week (180 picks Sun/Thu, 198 Mon, 216 Tue/Wed/Fri/Sat) because Powerball, Mega Millions, FL Lotto, and JTP only draw on specific weekdays. Daily games (Fantasy 5 Midday/Evening + Pick 2/3/4/5 Midday/Evening) generate every day. Each pick is locked in before the draw, then graded against the official result. Strategies are
Hot Bias · Contrarian · Due · AI Balanced · Gemini Quant · Random Baseline. The Random Baseline is the empirical control — over a sufficient sample, no other strategy should consistently beat it, because lottery games are statutorily i.i.d. random events. Cumulative net P&L is expected to trend negative over time. This ledger exists to show users honestly what each strategy bleeds, not to claim an edge.
Total Picks
—
Settled
—
Pending
—
Total Spent
—
Total Won
—
Net P&L
—
ROI
—
Win Rate
—
Cumulative Net P&L by Strategy
downward = expected · Random Baseline = empirical control
Strategy × Risk-Tier Performance (Settled Picks Only)
| Strategy | Risk Tier | Picks | Settled | Wins | Win Rate | Spent | Won | Net | ROI |
|---|---|---|---|---|---|---|---|---|---|
| Loading… | |||||||||
All Picks (0)
Page 1
Issued vs Drawn: Picks are generated 06:00 ET on the Issued date. The Drawn column shows the actual draw — for games that don't draw daily (Powerball Mon/Wed/Sat, Mega Millions & JTP Tue/Fri, FL Lotto Wed/Sat), Drawn is the next scheduled draw at-or-after Issued.
| Issued | Game | Strategy | Risk | Numbers (pick / draw) | Special | Cost | Drawn | Match | Prize | Net | Outcome |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Loading… | |||||||||||
Disclosure: Lottery games are statutorily games of chance. Every individual ticket remains negative-EV in expectation. This ledger is a simulated discipline check showing what your P&L would have been following each strategy verbatim — it is NOT evidence of a winning edge. Past performance does not predict future outcomes. Subscription fees access analytics only; tickets must be purchased separately at licensed Florida retailers. 18+. 1-888-ADMIT-IT · Florida Council on Compulsive Gambling.
🎟️ Scratch-Off Execution & Geo-Bounty Tracker
ELITE
How to use the Scratch Ledger:
Log your scratch-off purchases here to track your true P&L against the EV math.
Geo-Bounty: Enter your Target ZIP. The system continuously scans the FL Lottery database. If a top prize for your watched game is claimed in your region, the status will flash BURNED to prevent you from buying depleted inventory.
| Date Logged | Game | Qty | Cost | EV at Purchase | Geo-Bounty Status | Result (Winnings) | P&L |
|---|---|---|---|---|---|---|---|
| No scratch-offs tracked yet. | |||||||
Data Infrastructure
Scraper + API Integration
Production-ready scrapers for Florida Lottery data feeds
Node.js + Puppeteer / Cheerio
// LottoLogicIQ — Node.js Scraper (Puppeteer + Cheerio) // Scrapes: floridalottery.com/games/scratch-offs + draw results // Run daily via cron: 0 6 * * * node scraper.js const puppeteer = require('puppeteer'); const cheerio = require('cheerio'); const axios = require('axios'); const fs = require('fs'); const path = require('path'); // ── CONFIG ────────────────────────────────────────────── const CONFIG = { baseUrl: 'https://floridalottery.com', scratchUrl: 'https://floridalottery.com/games/scratch-offs', drawUrl: 'https://floridalottery.com/games/draw-games', gameIds: [1555,1562,1590,1594,1597,1604,1606, 1608,1618,1619,1620,1621,1622,1623,1627], outputDir: './data', delay: 1500 // ms between requests (be respectful!) }; // ── SCRAPE SINGLE SCRATCH GAME ────────────────────────── async function scrapeScratchGame(gameId) { const url = `${CONFIG.baseUrl}/games/scratch-offs/view?id=${gameId}`; const res = await axios.get(url, { headers: { 'User-Agent': 'Mozilla/5.0 (compatible; LottoLogicBot/1.0)' } }); const $ = cheerio.load(res.data); const prizes = []; // Parse prize table $('.odds-prizes-table tr, table tr').each((i, row) => { const cells = $(row).find('td'); if (cells.length >= 3) { const prizeText = $(cells[0]).text().replace(/[$,]/g,'').trim(); const oddsText = $(cells[1]).text().match(/[\d,]+$/)?.[0] || '0'; const remText = $(cells[2]).text().trim(); const [rem, total] = remText.split(' of ').map(x => parseInt(x.replace(/,/g,''))); if (isNaN(rem)) return; prizes.push({ prize: +prizeText, odds: +oddsText.replace(/,/g,''), rem, total }); } }); const topPrize = $('[data-top-prize], .top-prize').first().text().replace(/[$,]/g,'').trim(); const topRemaining = $('.top-prizes-remaining').first().text().trim(); const overallOdds = $('.overall-odds').first().text().replace('1:','').trim(); return { gameId, topPrize: +topPrize || 0, topRemaining, overallOdds, prizes, scrapedAt: new Date().toISOString() }; } // ── SCRAPE ALL GAMES ───────────────────────────────────── async function scrapeAll() { console.log('[LottoLogic] Starting scrape...', new Date().toISOString()); const results = {}; for (const id of CONFIG.gameIds) { try { results[id] = await scrapeScratchGame(id); console.log(` ✓ Game #${id} — ${results[id].prizes.length} prize tiers`); } catch (e) { console.error(` ✗ Game #${id}:`, e.message); } await new Promise(r => setTimeout(r, CONFIG.delay)); } const outPath = path.join(CONFIG.outputDir, `scratch_${Date.now()}.json`); fs.writeFileSync(outPath, JSON.stringify(results, null, 2)); console.log(`[LottoLogic] Saved to ${outPath}`); return results; } // ── SCRAPE DRAW RESULTS ────────────────────────────────── async function scrapeDrawResults() { const browser = await puppeteer.launch({ headless: 'new' }); const page = await browser.newPage(); await page.goto('https://floridalottery.com/games/draw-games/winning-numbers'); await page.waitForSelector('.winning-numbers', { timeout: 10000 }); const drawData = await page.evaluate(() => { const results = []; document.querySelectorAll('.draw-result-row').forEach(row => { const game = row.querySelector('.game-name')?.textContent; const date = row.querySelector('.draw-date')?.textContent; const nums = [...row.querySelectorAll('.ball')].map(b => +b.textContent); results.push({ game, date, numbers: nums }); }); return results; }); await browser.close(); return drawData; } scrapeAll().then(data => console.log('Complete', Object.keys(data).length, 'games'));
Python + BeautifulSoup + Selenium
# LottoLogicIQ — Python Scraper # pip install requests beautifulsoup4 selenium pandas schedule import requests, json, time, schedule, logging from datetime import datetime from bs4 import BeautifulSoup import pandas as pd logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s') BASE_URL = "https://floridalottery.com" GAME_IDS = [1555,1562,1590,1594,1597,1604,1606, 1608,1618,1619,1620,1621,1622,1623,1627] HEADERS = {"User-Agent": "LottoLogic/1.0 (educational research)"} def scrape_game(game_id: int) -> dict: url = f"{BASE_URL}/games/scratch-offs/view?id={game_id}" r = requests.get(url, headers=HEADERS, timeout=10) r.raise_for_status() soup = BeautifulSoup(r.text, "html.parser") prizes = [] for row in soup.select("table tr"): cells = row.find_all("td") if len(cells) < 3: continue prize_str = cells[0].get_text().replace("$","").replace(",","").strip() odds_str = cells[1].get_text().replace(",","").strip() rem_str = cells[2].get_text().strip() try: rem, total = [int(x.replace(",","")) for x in rem_str.split(" of ")] odds_val = int(odds_str.split("-in-")[-1]) prizes.append({"prize": int(prize_str), "odds": odds_val, "rem": rem, "total": total}) except: continue return {"game_id": game_id, "prizes": prizes, "scraped_at": datetime.utcnow().isoformat()} def calc_ev(game: dict) -> float: return sum(p["prize"] * (1/p["odds"]) * (p["rem"]/p["total"]) for p in game["prizes"]) def daily_scrape(): logging.info("Starting daily FL Lottery scrape...") results = {} for gid in GAME_IDS: try: results[gid] = scrape_game(gid) ev = calc_ev(results[gid]) logging.info(f" Game #{gid}: EV=${ev:.2f}, {len(results[gid]['prizes'])} tiers") time.sleep(1.5) except Exception as e: logging.error(f" Error game #{gid}: {e}") fname = f"data/scratch_{int(time.time())}.json" with open(fname, "w") as f: json.dump(results, f, indent=2) logging.info(f"Saved {len(results)} games to {fname}") # Schedule daily at 6 AM ET schedule.every().day.at("06:00").do(daily_scrape) if __name__ == "__main__": daily_scrape() # run once immediately while True: schedule.run_pending(); time.sleep(60)
REST API Specification
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/games | All active scratch games |
| GET | /api/games/:id | Game detail + prize structure |
| GET | /api/ev/:id | Expected value calculation |
| GET | /api/rankings | Ranked game list by score |
| GET | /api/draw/:game | Draw game history + hot/cold |
| GET | /api/budget/:amount | Optimized play plan |
| POST | /api/simulate | Monte Carlo simulation |
| POST | /api/alerts | Set prize-remaining alert |
// Express.js API server — app.js const express = require('express'); const { scrapeAll, calcEV } = require('./scraper'); const app = express(); app.use(express.json()); // Auth middleware const auth = (req, res, next) => { const key = req.headers['x-api-key']; if (!key || !validKeys.has(key)) return res.status(401).json({ error: 'Invalid API key' }); next(); }; app.get('/api/games', auth, async (req, res) => { const data = loadLatestData(); res.json(Object.values(data).map(g => ({ id: g.gameId, ev: calcEV(g).toFixed(2), ...g }))); }); app.get('/api/budget/:amount', auth, (req, res) => { const b = +req.params.amount; res.json(optimizeBudget(b, loadLatestData())); }); app.post('/api/simulate', auth, (req, res) => { const { gameId, tickets, sims } = req.body; res.json(monteCarlo(gameId, tickets, sims || 10000)); }); app.listen(3000, () => console.log('LottoLogic API running on :3000'));
Automated Daily Pipeline
# crontab -e — add this line for daily 6 AM ET scrape: # 0 11 * * * cd /app && node scraper.js >> logs/scrape.log 2>&1 # GitHub Actions workflow (.github/workflows/daily-scrape.yml): --- name: Daily FL Lottery Scrape on: schedule: - cron: '0 11 * * *' # 6 AM ET = 11 UTC workflow_dispatch: # allow manual trigger jobs: scrape: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '20' } - run: npm ci - run: node scraper.js env: DB_URL: ${{ secrets.DATABASE_URL }} WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK }} - uses: actions/upload-artifact@v4 with: name: scrape-data path: data/*.json retention-days: 30 # Docker Compose for full stack: --- version: '3.8' services: api: build: . ports: ["3000:3000"] environment: - DB_URL=postgresql://postgres:pass@db:5432/lottoedge db: image: postgres:16 volumes: [pgdata:/var/lib/postgresql/data] scheduler: build: . command: node scheduler.js depends_on: [db] volumes: pgdata:
Webhooks & Alert System
// Alert system — sends Discord/Slack/Email when key events occur const alerts = { // Trigger: top prize count drops (someone won!) topPrizeClaimed: async (gameId, prizeTier, newCount) => { const msg = { embeds: [{ title: `🎰 TOP PRIZE CLAIMED — Game #${gameId}`, description: `$${prizeTier.toLocaleString()} prize won! **${newCount} remaining**`, color: 0xFF4D6D, timestamp: new Date() }] }; await axios.post(process.env.DISCORD_WEBHOOK, msg); }, // Trigger: EV crosses threshold (game becomes better value) evThreshold: async (gameId, ev, price) => { if (ev / price > 0.85) { // 85%+ return threshold await axios.post(process.env.SLACK_WEBHOOK, { text: `⚡ HIGH EV ALERT: Game #${gameId} at $${ev.toFixed(2)} EV on $${price} ticket` }); } }, // Daily digest email via SendGrid dailyDigest: async (topPlays) => { await sgMail.send({ to: process.env.ALERT_EMAIL, from: '[email protected]', subject: `LottoLogic Daily Brief — ${new Date().toDateString()}`, html: buildEmailHTML(topPlays) }); } }; // Check for changes after each scrape async function detectChanges(prev, curr) { for (const [id, game] of Object.entries(curr)) { const p = prev[id]; if (!p) continue; // Top prize claimed? if (p.topPrizeCount > game.topPrizeCount) await alerts.topPrizeClaimed(id, game.topPrize, game.topPrizeCount); // EV improvement? await alerts.evThreshold(id, calcEV(game), game.price); } }
Data Export & Reports
Export Center
Download all analytics data as CSV or Excel for offline analysis, Excel modeling, or Python/Pandas import
📊 Scratch-Off Full Analysis
Exports all 15 scratch-off games with: EV, ROI, Sharpe, Kelly fraction, Edge Score,
prize structure per tier, top-prize freshness, drawdown estimate, and composite rankings.
🎰 Draw Games Analytics
Exports all draw games with: jackpot amount, ticket cost, EV, expected ROI, hot/cold/due numbers,
draw history count, backtester summary (if run), and strategy recommendations.
🤖 Backtester Results
Exports the full backtester history table: draw dates, actual numbers, AI picks per strategy,
hit counts, prize amounts, and cumulative ROI. Requires backtest to be run first.
📦 Full Portfolio Report
Master export: scratch-offs + draw games + strategy recommendations + statistical tests + Kelly sizes in one file.
Best for Excel modeling or sending to analysts.
🎯 Strategy Recommendations
Exports today's optimal play plan, budget allocations, AI number picks, EV trigger signals,
contrarian picks, and anti-split recommendations.
🔥 Hot/Cold Number History
Exports number frequency data per draw game: frequency counts, probability %, chi² deviation,
hot/cold classification, gap analysis, and signal composite scores.
Export Preview — Scratch-Off Data
| Game ID | Name | Price | EV | ROI % | Edge Score | Sharpe | Kelly % | Top Prize | Top Rem | Top Tot | Top % | Odds | Launched | Rec |
|---|
Preview shows first 10 rows of scratch-off export. Actual exports include all rows and additional columns.
Export Notes: CSV files open in Excel, Google Sheets, or any data tool.
Excel (.xlsx) exports use multi-sheet format — one sheet per data category.
All monetary values are in USD. ROI and probability values are expressed as percentages (%).
Data reflects current static + live Supabase values. Re-export after 6 AM ET daily scrape for freshest data.
SaaS Subscription Tiers
Choose Your Edge
Professional-grade lottery intelligence for serious players
All subscriptions include 7-day free trial · Cancel anytime · 18+ only · Gambling involves risk · Play responsibly · 1-888-ADMIT-IT
Subscription fees are for analytics access only — not lottery purchases. Tickets must be purchased separately at licensed Florida retailers.
Subscription fees are for analytics access only — not lottery purchases. Tickets must be purchased separately at licensed Florida retailers.