How to Develop a Non-Runner Tracking System
The Gap Everyone Ignores
Most racing analysts chase the winners, forgetting the horses that never make the start. Those “non‑runners” slip through data nets like ghosts, and the odds get skewed. Here’s the deal: you need a system that flags every withdrawal before the tote opens, not after the fact.
Step 1 – Capture the Source Feed
First, grab the official racecard XML stream. It’s raw, it’s messy, it’s where the magic lives. Pull the feed every five minutes with a cron job; any longer and you’ll miss the late scratches. By the way, use a lightweight parser like lxml in Python – it’s fast, it’s reliable.
Why Frequency Beats Freshness
Speed beats completeness. If you poll at 30‑second intervals, you’ll catch a horse that drops out at 14:55, not the one that disappears at 14:57. The difference is a few seconds, but the betting impact is huge.
Step 2 – Normalize the Data
All feeds speak different dialects. Convert every entry to a uniform schema: race_id, horse_name, status, timestamp. Two‑word punch: Keep it clean. This step is where errors implode if you skip it. Use regex to strip stray spaces, enforce uppercase for horse names – consistency is king.
De‑Duplication Is Not Optional
Multiple sources will report the same scratch. Your engine must dedupe by race_id + horse_name, picking the latest timestamp. If you let duplicates linger, you’ll over‑count non‑runners and break your metrics.
Step 3 – Store with Purpose
Relational tables feel safe, but a time‑series DB like InfluxDB lets you query “how many scratches in the last hour?” with a single line. Store raw feed as JSON for audit, then flatten into a stats table for quick look‑ups.
Index Wisely
Index on race_id and status. Anything else is baggage. When you need to pull “all non‑runners for today”, the query runs in milliseconds, not seconds.
Step 4 – Build the Alert Engine
Now the fun part. Set up a trigger that fires when status flips to “withdrawn”. Push a webhook to your betting UI, flash a banner, or dump into a Slack channel. Here is why: manual checks are dead weight; automation keeps you ahead.
Signal Filtering
Don’t scream every time a horse is scratched. Tier the alerts: high‑impact races (Group 1, Grade 1) get instant push, lower tiers get a daily digest. Noise kills adoption.
Step 5 – Validate and Refine
Run a back‑test against historic racecards. Compare your flagged list with the official “Did Not Run” column on horseracingnonrunners.com. Aim for 99.5% accuracy; anything less is unacceptable.
Continuous Loop
Every week, pull new racecards, measure false positives, tweak your regex, tighten your schedule. The system lives in a loop, not a one‑off script.
Step 6 – Integrate with Odds Calculators
Plug the non‑runner feed directly into your odds engine. Remove the horse from the pool, recalculate the probabilities, update the odds instantly. That’s the edge bettors crave.
Final Piece of Advice
Start with a single race, perfect the pipeline, then scale. Don’t overengineer; just get the core working and let data drive the upgrades. Shoot for speed, enforce uniformity, and you’ll own the non‑runner game.

