# Soccer Dixon-Coles Match Predictor (`commodus67/soccer-dixon-coles-match-predictor`) Actor

Get win/draw/loss, Over/Under 2.5, BTTS and correct-score probabilities for upcoming soccer matches, computed from a Dixon-Coles bivariate Poisson model fitted on each team's real ESPN match history. Covers MLS, Liga MX, and 6 other leagues with per-match prediction markets.

- **URL**: https://apify.com/commodus67/soccer-dixon-coles-match-predictor.md
- **Developed by:** [ELIO LIBERATORE](https://apify.com/commodus67) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 match predictions

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Soccer Dixon-Coles Match Predictor

Per-match soccer probabilities computed from a real statistical model — not a scrape of someone else's picks.

This Actor fits a **Dixon-Coles bivariate Poisson model** (Dixon & Coles, 1997) to each team's recent results, then uses it to price every upcoming fixture in the league: 1X2 (home/draw/away), Over/Under 2.5 goals, Both Teams To Score, and the 5 most likely exact scorelines — all derived from the same attack/defense ratings and expected goals (λ), so the numbers are internally consistent (they always sum to 1) instead of independently-guessed percentages.

### Why Dixon-Coles instead of a raw Poisson model?

A plain Poisson model assumes a team's home and away goals are independent, which overstates how often 0-0, 1-0, 0-1 and 1-1 actually happen. Dixon-Coles adds a low-score correlation correction (`rho`) fitted from the league's own history, plus exponential time-decay so recent form matters more than a result from three years ago. The result is a model built for exactly the markets that sportsbooks and prediction-market platforms (Kalshi, Robinhood Prediction Markets) price on a per-match basis.

### What you get

For every scheduled fixture in the chosen league and time window, one dataset row with:

- **1X2**: `prob1` (home win), `probX` (draw), `prob2` (away win)
- **Over/Under 2.5 goals**: `probOver25`, `probUnder25`
- **Both Teams To Score**: `probBttsYes`, `probBttsNo`
- **Top 5 scorelines** with their individual probabilities
- The fitted **expected goals** (`lambdaHome`, `lambdaAway`) and league **rho**
- Metadata: how much history was used, when the prediction was computed, and a `dataQuality` flag for fixtures involving a team with no historical matches (e.g. newly promoted)

### Supported leagues

Verified end-to-end against live ESPN data: **MLS** (`usa.1`), **Liga MX** (`mex.1`), **Liga de Expansión MX** (`mex.2`), **Brasileirão Série B** (`bra.2`), **USL Championship** (`usa.usl.1`), **Primera División Uruguay** (`uru.1`), **Categoría Primera A Colombia** (`col.1`), and **Eliteserien Norway** (`nor.1`) — the leagues that also have per-match event contracts on Kalshi and Robinhood Prediction Markets. You can also type in any other ESPN soccer league slug; the model will work as long as ESPN has enough historical results for that league.

### Input

| Field | Description | Default |
| --- | --- | --- |
| `leagueSlug` | ESPN league slug (pick from the list or type your own) | `usa.1` |
| `seasonsBack` | Years of history to fit team ratings on | `3` |
| `xi` | Daily time-decay rate (higher = recent form matters more) | `0.0018` (~1 season half-life) |
| `upcomingDays` | How many days ahead to predict | `14` |
| `maxGoals` | Highest per-team scoreline modeled | `10` |

### How it works

1. Pulls finished matches for the selected league from ESPN's public scoreboard API, going back `seasonsBack` years.
2. Fits each team's attack and defense strength plus a league-wide home-advantage and baseline via maximum likelihood (weighted so older matches count less).
3. Fits the Dixon-Coles `rho` correlation parameter for low-scoring games.
4. Pulls scheduled (not yet played) fixtures for the next `upcomingDays` days.
5. Builds a full score-grid per fixture (0-0 through `maxGoals`-`maxGoals`) with the Dixon-Coles correction applied, normalizes it to 1, and derives every market from that single grid.

### A note on newly promoted or newly added teams

If a team has no historical matches in the lookback window (typically a side newly promoted from a lower division), it's treated as league-average strength until it plays enough games to build a real rating. Those fixtures are flagged `dataQuality: "partial-new-team"` so you can decide how much weight to give them.

### Use cases

- Comparing model-implied probabilities against live prices on Kalshi/Robinhood per-match soccer contracts
- Building your own value-betting or trading workflow on top of consistent, per-match probabilities
- Research and analysis of goal-scoring patterns across leagues

# Actor input Schema

## `leagueSlug` (type: `string`):

ESPN league slug. Pick one of the leagues verified for this Actor (these are the ones with per-match markets on Kalshi/Robinhood), or type any other ESPN soccer slug — the model works on any league with enough historical matches on ESPN.

## `seasonsBack` (type: `integer`):

How many years of finished matches to pull from ESPN to fit each team's attack/defense ratings.

## `xi` (type: `number`):

Daily exponential decay applied to older matches when fitting ratings. Higher values make recent form matter more. The default gives a half-life of about 385 days (roughly one season).

## `upcomingDays` (type: `integer`):

How many days ahead of today to look for scheduled fixtures to predict.

## `maxGoals` (type: `integer`):

Highest per-team scoreline included in the score grid. The default covers over 99.9% of the probability mass.

## Actor input object example

```json
{
  "leagueSlug": "usa.1",
  "seasonsBack": 3,
  "xi": 0.0018,
  "upcomingDays": 14,
  "maxGoals": 10
}
```

# Actor output Schema

## `predictions` (type: `string`):

One row per upcoming fixture with 1X2, Over/Under 2.5, BTTS and top-5 scoreline probabilities, expected goals and the fitted Dixon-Coles parameters.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("commodus67/soccer-dixon-coles-match-predictor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("commodus67/soccer-dixon-coles-match-predictor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call commodus67/soccer-dixon-coles-match-predictor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,commodus67/soccer-dixon-coles-match-predictor"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/DLMafkS5FgWAhi3Zw/builds/a4KKzdq0jsJkQWWtv/openapi.json
