# Changelog of Horse Racing Pulse (`0xgollum/horse-racing-pulse`) Actor

- **URL**: https://apify.com/0xgollum/horse-racing-pulse/changelog.md
- **Full Actor documentation**: https://apify.com/0xgollum/horse-racing-pulse.md

## Changelog

### 0.3.0 — Full source filters + race context columns (23/09/2026)

**Added**

- **Filter at source** — 19 optional filters, applied before `max_races`, so
  excluded races are never fetched nor billed: `countries`, `meetings`
  (partial, accent-insensitive — `LONGCHAMP` matches `PARISLONGCHAMP`),
  `disciplines`, `categories` (`HANDICAP` matches every handicap variant),
  `surfaces`, `going`, `age_conditions`, `sex_conditions`, `track_directions`,
  `min/max_distance_m`, `min/max_prize_eur`, `min/max_runners`,
  `start_after`/`start_before` (+ `filter_timezone`), and horse-level
  `min/max_odds`. Measured live: French flat only = 171 rows instead of 398.
- **Race context on every row**: `discipline` (already read from PMU but
  dropped before output), `category`, `distance_m`, `prize_eur`, `runners`,
  `surface`, `going`, `age_condition`, `sex_condition`, `track_direction`.
- Same filter engine as World Turf Pulse — a filter set works in both.

Requested by a user in the Issues tab — thanks, Achirama.

### 0.2.8 — Relative movement rule (09/09/2026)

**Added**

- **Outsider steamers are now caught.** The signal used to fire only on an
  absolute move of `movement_threshold_pct` implied-probability points, which
  is blind to the classic outsider steam: 50/1 → 20/1 is only +3 points but
  +150 %. A second rule now fires when the implied probability moves by at
  least `movement_relative_pct` (default 30 %) of its previous value; moves
  on 200/1+ shots are ignored as noise. Signal rows carry `trigger`
  (`absolute` | `relative`) and `relative_change_pct`. Set
  `movement_relative_pct: 0` to keep the old behaviour.

### 0.2.7 — Cold review (09/09/2026)

**Fixed**

- **A false steamer/drifter on the first run of every day.** The run-over-run
  history was keyed on hippodrome + race + horse number, which is the same
  every day (Vincennes R1C1 #4 exists on every racing day) — so the first
  morning run compared today's horse against last night's *different* horse
  and fired a signal (measured: +45 pts). History is now dated on the PMU
  calendar day and ignored across midnight.
- **The steamer was the row `max_results` cut.** Rows were emitted snapshot
  first, so with the default cap (15) a run with one genuine steamer
  delivered 15 snapshots and no signal. Signals and form patterns now come
  first, snapshots after.
- **A race whose PMU call failed lost its odds history** for the next run —
  exactly when it was about to start. Horses not seen this run are carried
  forward within the day.
- **`earnings_swing` fired "-100 %" on every horse with no earnings yet this
  year** (most of them early in the season). Both years must now be non-zero.
- **PMU's programme date is the French calendar day**, not the container's
  UTC day (they differ between midnight and 2 am Paris time).

**Changed**

- History storage format is versioned (`{"schema": 2, "date": ..., "probs": {...}}`);
  a pre-upgrade history is treated as stale for one run.

### 0.2.1 — 2026-08-28

**Reliability hardening — every run now returns a result.**

- PMU has long dead windows (overnight, between meetings) with no races open
  for betting, and on a quiet run nothing moves. Previously the Actor pushed
  nothing in those cases, which made the run look like a failure. It now
  returns a single `status` row with a clear message so every scheduled run
  comes back clean.
- Input parsing hardened (`max_races`, `movement_threshold_pct`): a bad or
  `null` value now falls back to the default instead of crashing the run.
- Reads and writes of the run-history key-value store, and signal
  evaluation, are now each isolated — a storage hiccup can no longer fail a
  run, especially the post-delivery history write.

### 0.1.x / 0.2.0 — 2026-07 → 2026-08

- Live PMU (France) horse-racing odds movement: steamers & drifters between
  runs, optional hidden form patterns (debutant, winless streak, jockey
  change, earnings swing).
