Skip to content

About

Sports betting model for making a living.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

73 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Scare Bets — betmodel v5.4 engine, the Android app

Public name: Scare_Bets (display: Scare Bets). Internal id: Bet_Finder — unchanged in the Xii rename and again in the Scare Bets rename (2026-11-01), so on-device data carries over. App release: 13.3.1 (build 57) — the Scare Bets rebrand: display brand + the Pilot's ghost-barbell icon, internal id and storage untouched; 13.2.0 underneath stands unchanged, including the Show-default fix: the board opens on All markets (12.11.0's default opened on Golden bets, which hid every lane without a scored record). The ImageBoard of 12.11.0 stands unchanged: cards are drawn pictures (Design C odds-board rows on the Board, Design B tickets on Finds and Parse); the widget card system is deleted with the betmodel v5.4 engine. BetFi Xii (2026-10-24) is the Universal Model release: the engine's Organ 8 registry indexes every fit on the device, soccer prices across five leagues (EPL from the shipped fit; Serie A, La Liga, Bundesliga and Ligue 1 from real-results league fits), the menu auto-pulls on start and every 4 minutes, team/player names copy individually for search, Scare Charts render the live pull in-app (zoom via buttons — no sliders anywhere), and a Protected Slip sizes GOLDEN BET / BET HERE markets with the Kelly organ for the user to place and mark themselves. The service's core: the betmodel engine (deep mathematics, a multi-source ensemble, a fitted reparametrization layer, a cross-market coherence audit, and a coverage law — no bet left unchecked) behind a phone app whose face is one card. Analysis only: the app never places a bet, never asks for, touches, or stores FanDuel credentials. The menu pull reads the public board through the engine's read-only FanDuel sbapi route (Michigan), pull-on-demand, stamped with the pull time.

The two files (and why there are exactly two)

The Pilot's preference is 1 script. The engine honours it fully: betmodel5.py is one single self-contained script — the whole brain. Flet's build, however, requires the app entry point to be named main.py, so the shell is a second single file that imports the engine. Two Python files, no package tree, no module sprawl:

File What it is
betmodel5.py The engine (v5.2). Byte-identical copy of the lab's scripts/betmodel5.py — do not edit it here; engine changes happen in the lab and are re-copied.
main.py The entire Flet app: Board, Slip, Lab, 3D, More (+ Terms, Equations, Dev).
data/ The evidence pack: lab_export.json (the lab's exported record, stamped with its export time) plus the engine's data files (scorecard, lane history, phi registry, lane fits). Generated by the lab's export (export_lab_pack.py in the lab's mobile folder); the app seeds it into engine storage at startup.
instruments/ The lab's 11 self-contained HTML instruments (179,693 bytes), served in-app by the 3D shelf.
requirements.txt flet==1.0.4 and nothing else (the engine is stdlib-only).
.github/workflows/build-apk.yml The GitHub Actions build (below).
Scare-Bets.escb The current Complete Edition — the whole app as ONE file, ESCB/2 format (see the .escb section below). Generated, never hand-edited. (BetFi-10.escb / BetFi-11.escb are kept as history.)
build_escb.py The .escb builder: wraps main.py + betmodel5.py into the bundle.
armor.py The ESCB-T transmission armorer: base85 all-text form of a bundle.
ESCB-SPEC.md The .escb format specification and ruleset (v1 + v2).

The .escb file — Embedded Single-file Complete Bundle

Type: .escb = Embedded Single-file Complete Bundle. The format is specified in ESCB-SPEC.md. This repo ships ESCB/2: the bundle is a ZIP archive prefixed with a shebang line — Python executes ZIP archives containing a __main__.py (zipapp semantics), and ZIP readers find the archive regardless of the prefix. One file, three natures: executable, archive, and its own sources waiting to resurface. Backwards compatible with .zip: rename BetFi-10.escb to .zip and every standard tool opens it; renaming changes the name only, never a byte.

Meaning: BetFi-10.escb is BetFi 10 complete: the v5.2 engine and the v10.4.1 shell, compressed into a single distributable file — 94,977 bytes against the v1 prototype's 327,088 (29%). It is the same code the APK is built from — not a port, not a summary, not a demo build.

What the single file does and does not carry (v10.4.1): the repo bundle the APK builds from now also carries data/ (the evidence pack) and instruments/ (the 3D shelf). The single-file .escb still embeds engine + shell only. Run standalone, its Lab face prints "record not bundled" and its 3D shelf prints "instruments not bundled in this edition" — named states, never an empty record or a dead list. Extending the ESCB/2 payload to carry the two folders is follow-up work; the builder is unchanged in this release.

Structure, in order: ESCB.json (the manifest — format, versions, and the sha256 + size of every payload file; stored uncompressed so it reads without decompression), __main__.py (the stdlib-only bootstrap), then the payload: betmodel5.py and main.py, byte-identical to this repo's sources, with zero adaptations, each DEFLATE-compressed at level 9 (the only codec every ZIP tool reads; the spec prohibits BZIP2/LZMA entries).

On execution, the bootstrap locates its own archive, verifies every payload file against the manifest before running anything, then resurfaces the payload — byte-identical, under its real filenames — into a cache keyed by the bundle hash, and runs main.py from there. The app therefore runs with its real imports, its real file-based Dev-screen fingerprint, and its real main.py entry name, unmodified.

Usage:

  • Run the app: python3 BetFi-10.escb (needs flet==1.0.4 installed — the shell's only dependency; the engine is stdlib-only).
  • Open it as an archive: rename to .zip, or unzip BetFi-10.escb.
  • Verify a bundle: python3 BetFi-10.escb --verify (hash-checks the payload against the manifest). The Dev screen's fingerprint also identifies the resurfaced engine exactly.
  • Extract without running: python3 BetFi-10.escb --resurface DIR.
  • Engine alone: python3 BetFi-10.escb --engine prints the engine version + fingerprint from the resurfaced tree.
  • Text-only channels (chat, canvas): python3 armor.py BetFi-10.escb BetFi-10-armored.escb produces the ESCB-T form — the same bundle base85-encoded in an executable all-ASCII file (121,653 bytes); it decodes, hash-verifies, and delegates to the bundle's own modes.
  • Never hand-edit an .escb. It is generated from main.py + betmodel5.py by build_escb.py (python3 build_escb.py . BetFi-10.escb BetFi 10); edits land in those sources and the bundle is regenerated in the same commit. The two-file layout remains canonical because Flet's APK build requires an entry point named main.py — the .escb is the distribution form, the repo pair is the source form.

History: ESCB/1 (the prototype, through v10.1) was a plain-text Python file — engine embedded verbatim as a string bound as b5, shell with three marked adaptations, full raw size. ESCB/2 supersedes it; v1 bundles remain readable, builders no longer emit them. Full ruleset: ESCB-SPEC.md, rules R1–R13.

The screens

Bottom nav, five destinations: Board · Slip · Lab · 3D · More. More holds Terms, Equations and Dev only — the nav is capped at five permanently.

  • Board — the All cards | Finds segmented screen. All cards: every market the engine checked on the current pull, as a card. Face, in fixed order: matchup (soccer lists the home team first, world style), the lane's Win/Lose record, the pulled odds (soccer shows decimal first, American in parentheses), the hero Probability with the edge in points beside it, the Grade as colored text with the calibration chip (CALIBRATED / PROVISIONAL / UNCALIBRATED / UNTESTED — a status dot and the tag), then the verdict pill with the stance pill beside it (BULLISH / CONSERVATIVE / LONGSHOT — the cool tints, never a verdict color). UNPRICED gets the app's only outlined pill, so no-signal never reads as the DO NOT BET red. Depth stays in the card, collapsed: PRICE ANATOMY, SCALE, COHERENCE, PROVENANCE, each with a plain one-line gloss. A search box filters the board by any text the menu printed (teams, market name, league; every typed word must match). Toggles — Priced only · Golden only · Hide DO NOT BET · Quick bets (≤2h) · one switch per sport on the pull — and eight sorts (verdict ladder / edge (pts) / do-not-bets first / grade / probability / kickoff / Resolve date / pull order) re-render the cached checker pass; they never re-price. A filtered list says so: "{shown} of {total} markets". Finds (the Bet_Finder feed, merged into the Board): the GOLDEN BETS panel on top — every card whose engine verdict is GOLDEN BET, and when there are none it prints "No golden bets on this pull", never backfilled — then PRICED cards ranked by verdict ladder, then edge; price-conflict markets get their own group; everything else collapses into one "Checked — no edge" counter. The feed finds and ranks; it never upgrades a verdict. Buttons: Pull Menu (live pull; on failure the stamp reads UNVERIFIED and nothing is assumed) and Price Slate (re-runs the engine's coverage checkers over the pull). Offline, the app opens on the last pull, stamped with its original pull time — the engine's own stamp calls an old pull STALE. Stale is labelled stale.
  • Slip — the ticket tools behind a Parse | Parlay | Solver segmented control. Parse: paste a bet line ("Lions -3.5 (-110)", "Over 47.5 (-110)", "Team ML +150"…). The app reads selection, market, line, odds and implied probability, and when the last pull holds that market it shows the pull's own card for it. What it can't read or can't match, it says so — stamped, not guessed. Parlay: build a slip of up to four PRICED legs from the last pull. Cross-game slips print combined American + decimal odds, combined model probability (product of the legs' probabilities — independence assumed, printed on the page), EV per $1, a verdict in the ladder's language, and the slip's stance (the longest shot sets it) — and the combined grade is capped at the weakest leg's grade (the grouping law), disclosed on the page when the cap binds. Same-game slips print no combined number at all: the block is replaced by an UNPRICED stamp — "Same-game parlay — no correlation engine prices this; an independence product would be a lie of precision." (see the parlay law below). Solver: three solvers — stake for a target profit; Kelly sizing (full / half / quarter stakes, with the warning printed in full — Scare Bets sizes at quarter-Kelly); an equal-return hedge solver that prints a locked loss as a loss.
  • Lab — the record wing (below).
  • 3D — the instruments shelf (below).
  • Terms / Equations — the glossary and the math, in the open: every verdict term, edge, EV, implied probability, the grade band table, the stance rules, shrinkage, Kelly, parlay and hedge formulas, plus the v10.4.1 entries (evidence pack, Room Rule, same-game parlay, weakest-leg cap, closed-form WP, snapshot), each with a plain-English gloss.
  • Dev — app version + build, engine version + fingerprint (sha256 prefix + byte size) of the bundled betmodel5.py, the data-source line, the evidence-pack stamp (format + export time + seeded), the instruments count, and the credit: Scare Bets — by T. Abram. Engine: betmodel. Built with Praxis.

The Lab wing and the evidence pack

The Lab screen renders, top to bottom: Latest Pull (markets checked, PRICED, GOLDEN, price conflicts, calibration-tag and stance counts — the app's own live summary), Lane Ledger (each lane's Win/Lose of record, governor status, calibration tag — computed by the engine from the pack's scorecard and lane history), Lab Card (the pipeline's sealed paper cards — 2026-10-17: 3-3, −0.42u, CLV not captured — with the line that 4 packets were screened and held; screened is not sealed), Pilot Book (the Pilot's own plays on their own lines — the closed line $20 → $84, net +$64, and the two 2026-10-18 tickets printing PENDING), Kill Ledger (the count of barred patterns and the rule; full text lives in the lab), and the Rubric (the v5.2 grade bands and every named adjustment, printed from the engine's own constants).

The two books sit in separate sections with separate totals — no combined figure exists anywhere in the app (lab law: the books are never merged). The record flows one way, lab → app: the app reads the pack, the lab writes it.

The pack. data/lab_export.json + the engine's data files, exported by the lab (stamped exported_at). At startup the shell seeds the engine's storage from the bundled data/: missing files are copied; when the bundled export is fresher than the device's, the pack's files refresh as one unit; a newer device pack is never overwritten. The Lab face prints the stamp: "Lab record as of ⟨date⟩".

The Room Rule (the Pilot's order): the room is never empty — past stats exist. If a build carries no pack, the Lab prints "record not bundled" instead of any ledger — never an empty record dressed as 0-0. An empty room is a build failure, not a state.

The 3D shelf

Eleven instruments in three families — Stocks (Volatility Space 4D and its WebGL2 current edition, Volatility Space 3D, Stock 3D Map, CRM Terrain, CRM Path), Win Probability (WP Surface — WebGL2 current edition, WP Surface — Interactive, WP Surface — Static), NFL (Model vs Market Trajectories, Command Board). Every row carries its honest label: stock snapshots carry their window (SNAPSHOT · AUG 17 – OCT 16, 2026) and the one-sample footer (6 names, 44 sessions — observations, not laws); the live WP surfaces read MODEL — COMPUTED LIVE · JOURNEYS RECORDED; the NFL pieces are FROZEN · WEEK 6, 2026 (the command board's label also carries CONTAINS AN AUDIT FLAG). The WP instruments are the closed-form WP model — a different, simpler estimator than the engine's live Monte Carlo matrix, and they are named as such.

Serving route: the instruments are static HTML with no backend. Android browsers do not reliably render file:// paths into app-private storage and Flet 1.0.4 has no WebView, so the shelf serves instruments/ from a stdlib http.server bound to 127.0.0.1, port 8791 (increment fallback to 8800), started lazily on a worker thread the first time the shelf opens, and each instrument opens full-screen through the UrlLauncher service (verified in Flet 1.0.4: ft.UrlLauncher exists; page.launch_url does not). Server and launcher both fail quietly to printed states — if the folder is absent (single-file editions), the shelf prints "instruments not bundled in this edition".

Grading policy (v5.2 — Pilot-ordered)

Through v5.1, a lane whose calibration test had failed (the NFL lane: its phi does not beat its shrinkage/market benchmark) had its grades capped at C and its verdicts gated — the failure was enforced silently, in the grade itself. v5.2 removes the cap. Letter grades A+–F are computed from the model's edge math on every lane, and the grade bands are widened (B now starts at a +2.0-pt phi edge; the full table is on the app's Equations page and in the engine's GRADE_BANDS_V52). Calibration is now a displayed tag on every card — CALIBRATED / PROVISIONAL / UNCALIBRATED / UNTESTED — that informs the reader and blocks nothing. GOLDEN BET no longer requires a calibrated lane; it requires an A-band grade, a priced market, an edge still ≥ +3.0 pts at the band's pessimistic end, and a named mechanism. The phi/reliability diagnostics are still computed and shown (Lab screen); they set the tag, not a cap. The hard rules did not move: prices only from the live menu, UNPRICED ⇒ DO NOT BET with the named reason, the golden panel never backfilled. The engine regression (R1–R7 + the v5.2 addendum) is green under the new policy; R4's expectation was rewritten to assert the tag instead of the cap, and says so in its own text.

Stance (v10): every priced bet also carries a stance, computed by the engine from the bet's own probability, edge and price: BULLISH (strong edge on a side the model rates), CONSERVATIVE (high probability, thin edge — the boring-favorite profile), LONGSHOT (low probability or plus-money payout shape). Stance describes the shape of the bet, never whether to take it — the verdict decides that. UNPRICED bets get no stance.

The five verdicts (the ladder — engine-issued, app-printed verbatim)

  1. GOLDEN BET — A-band grade, priced, edge ≥ +3.0 pts at the band's pessimistic end, a named mechanism, no cautions.
  2. BET HERE — A/B-band grade, positive edge, no hard failure and no caution standing.
  3. RISK BET (BET) — a real edge with exactly one named caution (FRAGILE, record-less lane, a thin band floor).
  4. RISK BET (DO NOT BET) — a signal blocked by a named hard failure (kill ledger, Governor bench, C-band grade, coherence flag, a dead band floor) or by stacked cautions.
  5. DO NOT BET — the plain no: no edge, negative edge, or UNPRICED. Nothing there.

Build it (GitHub route — the only live route)

flet build apk is the build. (The Buildozer/Kivy route from old guides does not apply to a Flet app and is dead.)

  1. Create a GitHub repo named betmodel-v5 (private is fine).
  2. Push this folder's contents to it — main.py, betmodel5.py, requirements.txt, README.md, data/, instruments/, and .github/ — with the files at the repo root, not inside a subfolder. (The APK build packages the whole app folder: data/ and instruments/ ride along as app assets — that is what makes the Lab populated and the 3D shelf live on the phone.)
  3. In the repo: Actions → "Build Scare Bets APK" → Run workflow (it also runs automatically on pushes to main). First run takes a while: Flet fetches its Flutter SDK and builds with JDK 17.
  4. When the run is green, open it and download the artifact scare-bets-apk — that zip contains exactly two files: Scare-Bets.apk (release, the one to install — the arm64-v8a split, selected by name in the workflow; the Snapdragon 8 Gen 3 target build) and Scare-Bets-debug.apk (debug build).
  5. Copy the APK to the phone and sideload it (allow "install via USB" / install the file; it's signed with the build's default key for personal use — no Play Store involved).

If the Actions build ever rejects the pinned Flet 1.0.4 (the 1.x line is current and still settling), the known-stable fallback is the last 0.x line: change requirements.txt to flet==0.86.5 and re-run. The shell deliberately uses only long-stable Flet API surface either way.

Smoke-test checklist (first run on the phone)

  • App opens to the Board (All cards segment); the nav reads Board · Slip · Lab · 3D · More; header reads Scare Bets · engine betmodel v5.4 · analysis only.
  • With no pull yet, the menu stamp reads UNVERIFIED and the screen says so — nothing is pre-filled or assumed.
  • Pull Menu: the stamp updates to the pull time and source; the status line reports how many primary markets were pulled per sport (or names the failed scopes).
  • Price Slate: cards appear; each shows Win/Lose, Probability (or UNPRICED), a Grade, a calibration chip, the verdict pill and — when priced — a stance pill; the four collapsible sections open, led by the verdict_reason line.
  • Board toggles flip the list and the count reads "{shown} of {total} markets"; all eight sorts reorder without re-pricing. The Finds segment shows the GOLDEN BETS panel on top (golden cards, or "No golden bets on this pull").
  • Slip → Parse: the six example shapes parse; a matched bet shows the pull's card.
  • Slip → Parlay: two cross-game legs combine (combined odds, model %, EV, grade, slip stance print); two same-game legs print the UNPRICED stamp and no combined number.
  • Slip → Solver: all three solvers compute; bad input prints "Enter a number for every field." — never a crash.
  • Lab: populated on first open — lane ledger with the real record (NFL 3 W – 8 L), the sealed Lab Card (3-3, −0.42u), the Pilot Book with its PENDING tickets and the closed line, the pack's export stamp on the face.
  • 3D: the shelf lists 11 instruments in three families with their labels; tapping one opens it full-screen.
  • More → Terms / Equations / Dev all render; Dev shows the engine fingerprint, the evidence-pack stamp, the instruments count, and the credit.
  • Kill and relaunch the app offline: it reopens on the last pull, stamped with the original pull time (STALE once old).

Honesty rules carried into the app

  • A failed pull stamps UNVERIFIED; a market the engine cannot price stamps UNPRICED with its reason named. The app invents nothing — every number traces to an engine output with provenance.
  • The record the Lab shows is the lab's, shipped in the evidence pack and seeded into engine storage at startup — the lanes report their real Win/Lose and their earned tags (NFL prints its UNCALIBRATED fact). A build without the pack prints "record not bundled" (the Room Rule); nothing anywhere prints an empty record as if it were a record.
  • Same-game parlays print no combined number — the UNPRICED stamp with its reason — because no correlation engine prices them; an independence product would be a lie of precision. Cross-game combined grades are capped at the weakest leg, and the cap is disclosed on the page when it binds.
  • The Lab Card and the Pilot Book are never added together; screened packets are never presented as cards; the app never writes the lab's record and never un-bars a kill-ledger pattern.

About

Sports betting model for making a living.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages