Polytraders Dev Guide
internal
v3 spine Phase 1 · Shared contracts 9 demo-wired · 0 shadow-ready · 0 production-live · 100 pending · 109 total 15/33 infra tasks the plan status board

← All stages · stage 5 of 11

Stage 5

Fair-value engine

Turn the shared feature vector into a calibrated probability and a sensible uncertainty band.

Challenge we are solving

A point estimate p_hat with no uncertainty is dangerous. The same p_hat=0.67 with a 0.04 band is a different bet than with a 0.20 band.

What this stage does

Reads the feature vector, runs the scoring model, and emits p_hat, lower bound, upper bound, an uncertainty buffer, and a suppression reason if any precondition failed.

Why this stage exists

The next stage (execution) and the gate after it (risk) both need to know the *uncertainty*, not just the central estimate.

Flow

FeatureVectorfrom stage 4
Modelv=0.7.2
Calibrationisotonic
Outputp_hat · LB · UB
Suppression?if features incomplete

What the backend should expose

  • score_id, p_hat (0..1)
  • LB, UB (confidence band)
  • uncertainty_buffer (used by decision stage)
  • model_version, calibration_version
  • feature_completeness % (input quality)
  • suppression_reason (null when scoring proceeded)

Maths we expect here

Every formula below is implemented in packages/polytraders-bots/ or packages/polytraders-runner/. Treat the worked example as the unit-test sanity check you should be able to reproduce locally.

1

Point estimate p_hat

\[\hat p = \sigma(w^{\top} x + b),\qquad \sigma(z) = \tfrac{1}{1 + e^{-z}}\]
SymbolMeaningUnits / range
\(x\)Feature vector from stage 4R^n
\(w, b\)Model weights and biasR^n, R
\(\hat p\)Predicted probability YES resolves true0..1
worked example\[w^{\top}x + b = 0.71 \;\Rightarrow\; \hat p = \sigma(0.71) = 0.670\]

We do not trade \hat p alone. The uncertainty band below is just as important.

2

Confidence band (calibrated quantiles)

\[\text{LB} = Q_{0.10}(\hat p \mid x),\;\;\text{UB} = Q_{0.90}(\hat p \mid x)\]
SymbolMeaningUnits / range
\(LB\)10th-percentile of the calibrated posterior0..1
\(UB\)90th-percentile of the calibrated posterior0..1
worked example\[\hat p=0.670,\;\text{LB}=0.64,\;\text{UB}=0.71\]

Calibration is isotonic regression refit weekly on resolved markets. Wider bands → stage 7 cuts size.

3

Uncertainty buffer

\[buffer = \alpha \cdot (\text{UB} - \text{LB}) + \beta \cdot drift\]
SymbolMeaningUnits / range
\(\alpha\)Width-to-buffer multiplierdefault 0.5
\(\beta\)Drift-to-buffer multiplierdefault 1.0
\(drift\)Recent calibration drift vs. baseline0..1
worked example\[(\text{UB}-\text{LB})=0.07,\; drift=0.01 \;\Rightarrow\; buffer = 0.5{\cdot}0.07 + 1.0{\cdot}0.01 = 0.045\]

Stage 7 subtracts this from net_edge before approving a trade. Bigger band ⇒ bigger buffer ⇒ less likely to trade.

4

Brier score (model quality, backtest)

\[\mathrm{Brier} = \tfrac{1}{N}\sum_{i=1}^{N}\big(\hat p_i - y_i\big)^2\]
SymbolMeaningUnits / range
\(\hat p_i\)Predicted probability for market i0..1
\(y_i\)Realised outcome (0 or 1){0,1}
\(N\)Number of resolved markets in sample
worked example\[N=500,\; \mathrm{Brier}=0.181 \;\Rightarrow\; \text{better than uniform 0.25}\]

Stage 10 reports Brier per model_version. Promotion threshold: Brier ≤ 0.20 over the rolling 500-resolution sample.

How a developer codes this stage

Reference TypeScript implementation lives in packages/polytraders-* at the repository root. Stage owners maintain these files — read them before writing new code.

  • packages/polytraders-bots/src/strategyStrategy bots that produce p_hat. Reference: makertight, crossmarketarb.
  • packages/polytraders-contracts/src/OrderIntent.tsThe OrderIntent carries p_hat, LB, UB, buffer — it is the artefact this stage hands to execution.
  • packages/polytraders-backtest/src/engine.jsBacktest harness that scores model_version on historical event log → Brier.

See it in the platform mock

The platform mock is the source of truth for what each stage's UI exposes. Open these alongside the code references.

Reason codes emitted at this stage

  • STRAT_*STRAT — strategy, model, fair-value

Hover or tap any reason code on this page (or anywhere on the site) to see its canonical short description. Full registry: /standards/reason-codes.