hkjc_odds_combinations
Hong Kong horse racing live odds history and market movements
Download a file
CSV · Excel · Parquet · JSON. Filtered exports.
See pricingQuery with SQL
DBeaver, DuckDB, MotherDuck, or HTTPS. Sub-second latency.
Open connection detailsConnect to AI
MCP for Claude Desktop, Cursor, ChatGPT, Goose. 1-line install.
See setupThe Hong Kong Jockey Club's betting odds as they moved before each race: Win and Place for every runner, and the exotic pools (Quinella, Quinella Place, Forecast, Trio, First Four, Double, and HKJC's top-20 and banker lists for Tierce, Trio, First Four and Quartet). Track how prices changed from the first quote we captured to the close, see which runners attracted late money, and study market efficiency. One row per odds MOVEMENT per combination: each pool update HKJC publishes is stored as the full set of that pool's prices, timestamped with HKJC's own update time (snapshot_timestamp, UTC); repeated unchanged states are not stored, so hold a price flat until the next row. Our collector polls: if HKJC moves a pool more than once between two polls, only the later state is recorded. The polling interval by era was about 5 minutes for most of December 2021 to mid-2023 and late 2024 through 2025, about 1 minute from mid-2023 to Q3 2024, and about 1-2 minutes since late May 2026. Hong Kong meetings (Sha Tin and Happy Valley): Win and Place odds from 8 December 2021; Quinella, Quinella Place, Forecast, Trio, First Four and Double from 1 October 2024. 18 Hong Kong meetings in that span have no odds at all: 10 September 2023; 3, 6, 10 and 13 March 2024; 8, 11, 15, 18, 22, 25 and 28 September 2024; 3, 6 and 9 November 2024; and 7, 11 and 14 January 2026. Tierce and Quartet: the Hong Kong Jockey Club publishes no complete odds matrix for either pool, only the 20 lowest-priced combinations (TCETop, QTTTop) and, for each runner taken as banker, the 10 lowest-priced combinations with that runner first (TCEBanker, QTTBanker); Trio and First Four carry the same two lists (TRITop, FFTop, TRIBanker, FFBanker) beside their complete matrices. The top-20 lists run from 1 October 2024 but were not collected for meetings from 1 January 2026 to 24 May 2026; the banker lists exist for 8 meetings between 28 September 2025 and 27 December 2025 and for every meeting from 27 May 2026. Overseas races simulcast in Hong Kong (venues S1-S5) are included from 29 September 2024. Delivered hourly with the rest of the pipeline, not streamed.
Evaluate it in full below: the evidence and a working sample are open to everyone. Buy or subscribe to unlock the complete dataset — your account is created automatically at checkout.
The evidence
Schema & column quality (15 columns)
Scroll table sideways to see more columns →
| Column | Type | Description | Populated | Distinct |
|---|---|---|---|---|
| race_date | DateTime | Date of the race meeting (YYYY-MM-DD). | — | — |
| venue_code | String | Venue code: 'ST' (Sha Tin) or 'HV' (Happy Valley) for Hong Kong races, or S1-S5 for an overseas race simulcast in Hong Kong. Empty only where a row's venue could not be established, and then race_id is empty too. | — | — |
| race_number | Int32 | Race number within the meeting: 1-11 at Hong Kong meetings, 1-10 on simulcast cards. | — | — |
| race_id | Nullable(String) | Unique race identifier for joining with hkjc_races (format: ST_20250928_R01) | — | — |
| odds_type | String | HKJC pool code. The base pools: WIN, PLA (Place), QIN (Quinella), QPL (Quinella Place), FCT (Forecast), TRI (Trio), FF (First Four), DBL (Double), each a complete matrix of every combination. Suffixed variants are separate lists HKJC publishes alongside them: *Top = the 20 lowest-priced combinations (TCETop, TRITop, FFTop, QTTTop; QINTop/QPLTop on simulcast races); *Banker = for each runner taken as banker, the 10 lowest-priced combinations containing it (for TCE and QTT, with that runner first); *Pre = the pool's odds during HKJC's presales (advance-selling) period; PWIN0/PWIN1 = two Win-odds snapshot series HKJC publishes for its PWIN page, which its own site code names '1stBoost' and 'slide2m' (carried as published; HKJC does not document them further). There is no complete Tierce (TCE) or Quartet (QTT) matrix: HKJC does not publish one, so their Top and Banker lists are all the ordered Tierce and Quartet odds that exist. | — | — |
| odds_category | String | The bet the pool belongs to, grouping odds_type and its variants: Win/Place, Quinella (QIN, QPL), Forecast, Tierce, Trio, First Four, Quartet, Double. | — | — |
| combination | String | The bet, as HKJC writes it: a runner number for WIN/PLA ('01'); two-digit runner numbers joined by commas for single-race pools ('01,02' Quinella/Forecast, '01,02,03' Trio/Tierce, '01,02,03,04' First Four/Quartet); one runner per race joined by '/' for Double ('01/03'). Unordered pools (Quinella, Trio, First Four) list runners in ascending order; ordered pools (Forecast, Tierce, Quartet) in finishing order. | — | — |
| odds_value | Nullable(Float64) | Decimal odds as HKJC quotes them: the return per $1 staked, stake included (5.5 = $5.50 back for $1). HKJC displays every pool except Quartet capped at 999, so 999 means '999 or more' (a quarter of Trio rows and over half of First Four rows sit at the cap); Quartet runs to 99999. NULL where HKJC shows no price: a combination including a scratched runner (HKJC prints SCR) or a pool not yet priced. | — | — |
| is_hot_favourite | Nullable(Bool) | HKJC's hot-favourite flag on this runner or combination. NULL where HKJC publishes no flag (Banker-list rows). | — | — |
| snapshot_timestamp | DateTime64(3) | When this odds state was published by HKJC (UTC): the Jockey Club's own update time, not our collection clock (timestamp_source = 'hkjc_published'; the small residue where HKJC publishes no update time carries the collection clock instead, marked 'scrape_clock'). One row per movement: repeated unchanged states are not stored, so consecutive rows for a pool are genuine odds changes. Our collector polls rather than streams, so if HKJC moves a pool more than once between two polls only the later state is recorded. The polling interval by era: about 5 minutes for most of Dec 2021 to mid-2023 and late 2024 through 2025, about 1 minute mid-2023 to Q3 2024, and about 1-2 minutes since late May 2026. | — | — |
| timestamp_source | Nullable(String) | Where snapshot_timestamp comes from: 'hkjc_published' = HKJC's own published update time (the norm); 'scrape_clock' = our collection clock, used only where HKJC publishes no update time (certain exotic combination matrices, and a small residue of early-era rows whose embedded time could not be decoded). | — | — |
| observed_at | Nullable(DateTime64(3)) | When our collector first observed this odds state (UTC). The gap between observed_at and snapshot_timestamp bounds the detection latency; the spacing of observed_at values reflects the collection era's polling interval. | — | — |
| sell_status | Nullable(String) | Pool sale state at first observation, as published by HKJC: START_SELL (open for betting) or STOP_SELL (closed). NULL on the older collection eras that did not carry it. Use it to cut a race's series at market close cleanly. | — | — |
| updated_at | DateTime64(3) | Timestamp when the record was last updated. | — | — |
| id | String | Stable unique identifier for this row — the last column of every export. Use it to deduplicate, to key an incremental load, or to reference one specific row. It is additive: the entity and join keys you already use (race_id, horse_id, and the like) are unchanged. | — | — |
Race 1 of the latest completed race date, Win and Place pools first (pool codes in reverse order: WINPre, WIN, PWIN1, PWIN0, PLAPre, PLA), each newest update first, then the race's other pools, until the file's 10,000-row limit. For a Hong Kong meeting that is essentially every runner's Win price at each HKJC update running back from the off; where more than one venue ran a race 1 that day, their rows follow one another within each pool (venue codes in reverse order). The full product carries every race and pool in the same columns.
Choose your access
A Pass gives you freshness within a rolling window. The Full Archive gives you the full history we hold for the dataset, frozen at purchase. They solve different problems, and they work together.
One-off purchase
Full Archive
The full history we hold, frozen at purchase. Yours to keep.
Full details →- What you get
- The full history we hold, to your purchase date
- History depth
- Dec 2021 – present, in full
- Updates
- None. Frozen at purchase
- Delivery
- Gzipped CSV, opens in Excel; link valid 7 days
- API access
- Not included
- Access window
- Most recent 24 months, rolling
- Updates
- Continuous, within hours of the source
- Delivery
- API, SQL and downloads
- Exports
- Uncapped
Included Datasets
Get notified when this dataset is updated.
Questions about this data?
Our data experts are ready to help clarify any aspects of this dataset.
Contact Our Team