Skip to content

Response drift: smarkets — winner_count, complete, cashout_enabled, bet_delay, market_type fields not accessed by normalizer #2016

Description

@realfishsam

Exchange

smarkets

Severity

MEDIUM

What Our Normalizer Expects

core/src/exchanges/smarkets/normalizer.ts extracts a fixed set of fields from each market object: id, event_id, name, slug, description, category, categories. No market lifecycle fields (complete, winner_count) or trading-constraint fields (cashout_enabled, bet_delay) are accessed or included in sourceMetadata.

What The Live API Returns

The live GET https://api.smarkets.com/v3/events/?limit=3&state=upcoming response includes several unaccessed fields on every market object:

markets[].winner_count: int         ← how many outcomes can win (1 = binary, N = multi-winner)
markets[].complete: bool            ← whether the market has fully traded / closed
markets[].cashout_enabled: bool     ← whether cashout (early settlement) is available
markets[].bet_delay: int            ← seconds delay between bet placement and acceptance
markets[].market_type.name: str     ← canonical market type name (e.g. "winner")
markets[].market_type.param: str    ← type-specific parameter (e.g. over/under threshold)
markets[].info.reason: str          ← additional market metadata (e.g. suspension reason)

Endpoint tested: GET https://api.smarkets.com/v3/events/?limit=3&state=upcoming

Impact

MEDIUM:

  • winner_count: Without this, PMXT cannot distinguish binary markets from multi-winner markets. Placing orders on a "pick 3 of 5" market using binary-market assumptions produces incorrect probability calculations and incorrect order sizing.
  • complete: Closed/settled markets are indistinguishable from active ones in normalized output — closed markets appear live, misleading consumers.
  • cashout_enabled: Cashout offers are conditionally available. Without this flag, UI cannot show or suppress the cashout option per market.
  • bet_delay: Order execution logic cannot account for the acceptance delay, which affects time-sensitive strategies.
  • market_type.name/market_type.param: Market mechanics (e.g. correct score, handicap, over/under) cannot be surfaced to consumers, preventing type-specific display or routing.

Relationship to Existing Issues

Issue #1366 covers a separate finding: events[].end_date is null for all events. This issue is unrelated and tracks the unaccessed market-level operational fields.

Suggested Fix

Add all seven fields to the Smarkets raw market type definition and include them in SMARKETS_PROMOTED_MARKET_KEYS (or map them explicitly in the normalizer):

// SmarketsRawMarket — add fields
winner_count?: number;
complete?: boolean;
cashout_enabled?: boolean;
bet_delay?: number;
market_type?: { name: string; param?: string };
info?: { reason?: string };

Promote winner_count and complete as typed fields on UnifiedMarket if market-type routing or lifecycle filtering is needed downstream. Include the rest in sourceMetadata at minimum.


Found by automated response shape drift audit

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions