Skip to content

Architecture

pmlab is a core that knows nothing about any one market and a plugin per market family that knows everything about its own. The plugin turns a family's markets into rows; the core backtests, gates, trades and monitors those rows the same way for every family.

The pipeline

Polymarket API
      │
      ▼
MarketPlugin.discover_markets()  ──►  list[MarketSpec]
      │
      ├── fetch_features(spec, horizon)       ──►  dict[str, float]
      ├── fetch_truth(spec)                   ──►  float | str | None
      └── build_training_rows(spec, horizon)  ──►  list[dict]        (one row per bin)
                │
                ▼
        build_panel(rows)                      schema check, price-timing check, leakage check
                │
                ▼
        rolling_origin_eval(panel, model)      walk-forward: trains on decision_date < eval date
                │
                ├── BacktestMetrics            (PnL, hit rate, average edge)
                ├── brier_decomposition()      calibration diagnostics
                │
                └── HoldoutGateResult.evaluate(required_segments)
                            │
                      GO ───┴─── NO_GO  →  ChampionManifest.publish() raises ValueError
                      │
        ChampionManifest.publish(model, gate)
                      │
              champion.json + champion.pkl         (ModelRegistry archives every version)
                      │
        ┌─────────────┴──────────────┐
        │                            │
   PaperBroker                  LiveBroker
   paper trades,                real CLOB orders,
   segments from champion.json  dry_run=True to test first
        │
   SettlementEngine.settle_all(specs)              waits for plugin.is_truth_final(spec)
        │
   generate_report()  ·  pmlab monitor             HTML report · drift, calibration and PnL watchdog

What each package owns

The names are the public ones: import them from pmlab (or from the package named in the row). Module paths such as pmlab.core.costs are internal; see Public API and stability.

Package Responsibility
pmlab.core MarketSpec, OutcomeBin, Position, CostModel, TradePolicy, compute_edge, estimate_fee, flat_stake_size, kelly_fraction, kelly_stake_size, settle_position. No domain logic.
pmlab.plugins MarketPlugin (the ABC a family implements), PluginRegistry, WeatherTmaxPlugin (the reference plugin: temperature markets). pmlab.plugins.sports_f1 is a skeleton for categorical F1 markets.
pmlab.features add_lags, add_rolling_stats, encode_cyclical, encode_onehot, clip_outliers, add_missing_indicators, add_interactions, TargetEncoder, FittedTargetEncoder. See Features.
pmlab.data FeatureSnapshotStore (point-in-time), build_panel, build_panel_from_snapshots, check_no_leakage, check_price_timing. See Data layer.
pmlab.markets GammaClient, ClobClient, AsyncGammaClient, AsyncClobClient, DiskCache, TypedCache. See Async clients.
pmlab.backtest rolling_origin_eval, compute_metrics, BacktestMetrics, HoldoutGateResult, purged_kfold, embargoed_split. No lookahead.
pmlab.modeling MarketForecaster (the interface), LGBMForecaster, SklearnForecaster, EnsembleForecaster, ConformalForecaster, CalibratedForecaster, TunedForecaster, the calibrators, brier_decomposition, ChampionManifest, ModelRegistry. See Modeling.
pmlab.execution EdgeSignal, PaperBroker, SettlementEngine, LiveBroker, resettle_trades.
pmlab.monitoring drift_report, CalibrationTracker, health_report: the pure core of pmlab monitor. See Watchdog.
pmlab.reports generate_report: a self-contained HTML report.
pmlab.tracking LocalJSONTracker, ExperimentTracker, MLflowTracker (the track extra). See Tracking.
pmlab.reproducibility ReproducibilityRecord, BacktestConfig, run_backtest, capture_backtest, reproduce, load_record, fingerprint_panel: seeds, versions, config and a data hash per run, re-run and verified by pmlab reproduce.
pmlab.datasets load_sample(): the bundled synthetic weather sample and the offline clients that serve it.
pmlab.workspace WorkspaceContext: every path comes from a workspace, and workspaces never share one.
pmlab.cli The pmlab command. See Command line.

Extending it

A new market family is one class: subclass MarketPlugin, implement four methods, register it. See the plugin authoring guide. Optional heavy dependencies (Optuna, MLflow) stay behind extras and are never imported by the core install.