Markets
SportsPerp launches with 68 markets — 20 EPL teams and 48 rostered players. Every market is a perpetual future priced against the composite OBV Index, collateralized in USDC, and settled on Solana.
Market types
| Type | ID range | Count | Notes |
|---|---|---|---|
| Team | 0–19 | 20 | Contiguous — one market per EPL club, alphabetically assigned |
| Player | 20–99 | 48 | Sparse — IDs are permanent even as players transfer, get injured, or drop out of roster |
The market_type field on MarketConfig is 0 for teams, 1 for players. Market IDs are stored as u16 and used as PDA seeds.
Why stable, sparse IDs
A traditional listing system would re-index markets whenever the player roster changes — new signings get the next available slot, dropped players free their ID, existing markets shift. That’s a disaster for a perp protocol:
- Open positions reference market IDs. Reassigning an ID would either silently reassign positions (destructive) or force-close them (user-hostile).
- Historical candles are keyed by market ID. A reassignment severs the price history.
SportsPerp instead uses stable, sparse IDs in the 20–99 range for players. When a player leaves the roster, their market is paused and eventually sunset (see Market Lifecycle); their ID is never reused. A player who returns keeps their original market, price history, and any open positions.
The roster as single source of truth
roster.json at the repo root defines every market: ID, name, team affiliation, canonical source ID, position group, and metadata. The file is:
- File-watched. The engine hot-reloads when roster.json changes — no service restart required.
- Consumed by every service. Crank, oracle pusher, keeper, liquidator, frontend, and init scripts all read from the same file. No drift.
- Versioned. Currently v4 (every player entry carries an
sb_player_idfor stable identity across roster rotations). Changes are backed up automatically before being applied.
Roster updates are generated by a script that pulls the current EPL player pool from the data partner’s REST feed, applies the selection algorithm described in the next section, and fuzzy-matches against the existing roster to preserve market IDs.
Player selection algorithm
To keep player markets tradable, the roster algorithm enforces quality and diversity constraints:
- Fetch all EPL players (~535) from the data partner’s REST feed.
- Filter by minimum playing time: minutes ≥ 900 (~319 eligible).
- Rank each player by their composite z-score within position group (OBV 55% + Form 30% + Minutes 15%).
- Select the top 48 subject to:
- Position floors: ≥ 8 FW, ≥ 15 MF, ≥ 10 DF, ≥ 3 GK
- Team cap: ≤ 5 players per club (prevents stacking on the best teams)
- Fuzzy-match against existing roster names to preserve stable IDs.
- Back up the previous roster before writing.
The cap on players-per-team is deliberate: a trader wanting leveraged exposure to the top club gets the team market (ID 0–19); player markets are for speculating on individual performance, not dodging the team-market liquidity.
Market volatility characteristics
Teams and players have different risk profiles:
| Dimension | Team markets | Player markets |
|---|---|---|
| Signal window | Whole club across 38 matches | Individual across 24–38 appearances |
| Volatility drivers | Results, manager changes, European fixtures | Injuries, transfers, rotations, suspensions |
| Confidence interval | Tighter (300–800 bps) | Wider (400–1000 bps) |
| Default max leverage | 5x | 5x (same base; confidence scaling narrows in practice) |
Player markets are inherently more volatile. A transfer rumor, a minor injury, or a manager’s rotation decision can move the index sharply before any on-pitch impact is observed. The wider confidence interval triggers automatic leverage reduction during high-uncertainty windows (Margin).
Current state
- Program ID:
6d4fSCD7mNy7aDNS2mXUxYpZjFFQKBKwAsM5kojKQA6h(devnet) - Markets deployed: 20 teams + 48 players = 68 active
- Next update: weekly roster regeneration as the EPL season progresses
Further reading
- Contract Specifications — the full per-market spec: fees, leverage, funding interval.
- Market Lifecycle — initialization, pausing, sunsetting, settlement.
- Composite Index Design — how market prices are derived.