Why
A model that outputs a probability cannot be graded with accuracy, and the substitution is the most common quiet mistake in applied work. Accuracy, precision, recall and F1 all require a threshold: somewhere the 0.63 becomes a yes. That threshold is a decision about costs, not a property of the forecast, and once it is applied the number you actually sized a position with has been discarded. A forecaster that is right 100% of the time on the questions it answers has not demonstrated skill — it has demonstrated that it only answers easy questions.
The correct grade for a probability is a proper scoring rule, meaning one whose expected score is optimised by reporting your true belief. Two are worth knowing. The Brier score is mean squared error on probabilities, it is bounded, and it decomposes cleanly, which is why it is the useful one here. The log score is the only local proper rule, and it punishes confident wrongness without limit — assign 0.001 to something that happens and the score is unbounded. The choice between them is a choice about whether one catastrophic call should dominate the record, and for a trading agent it usually should.
Then the trap, and it is the reason this card is not simply "calibrate your model". Calibration alone is worthless. A forecaster that ignores every question and always reports the base rate is perfectly calibrated — when it says 30%, the thing happens 30% of the time — and it is useless, because it never distinguishes one case from another. Murphy's decomposition of the Brier score names the two halves separately: reliability is whether your stated probabilities match observed frequencies, resolution is whether you push probabilities away from the base rate in the right direction. Calibration without resolution is a thermometer that always reads the seasonal average. Both numbers are needed, and only the decomposition shows which one you lack.
And there is a baseline sitting right there that most projects never use. On a prediction market the price is a probability, produced by everyone else's money, on exactly the questions being forecast, at exactly the moment of the decision. Scoring the agent against the market on identical events costs one extra logged column and settles the only question that matters — not "is the forecaster good" but "is it better than the number that was free". priced-by-the-wrong-thing argues that an instrument can answer a different question than the one being asked; this is the same discipline applied to your own output.
Finally, the reason it is not academic. Position sizing under Kelly is a function of the probability itself, not of a classification. A forecast that is directionally right but systematically overconfident produces bets that are systematically too large, and the account dies while the hit rate looks fine. Miscalibration does not show up as wrong answers. It shows up as the wrong bet size, which is a different failure and a worse one.
How it works
What each score can and cannot see
| Metric | Needs a threshold | Rewards honesty | Sees overconfidence | Note |
|---|---|---|---|---|
| Accuracy / F1 | Yes | No | No | Discards the magnitude you sized the bet with |
| AUC | No | No | No | Only ranking. A model that outputs p/10 for every p has identical AUC and is unusable |
| Brier | No | Yes | Yes | Bounded, and decomposes into reliability + resolution + uncertainty |
| Log score | No | Yes | Unboundedly | Local; one confident miss can dominate the whole record |
The AUC row is the one that catches people. Ranking metrics are invariant to any monotone squashing of the probabilities, so a systematically overconfident model and a well-calibrated one can score identically — and only one of them can be traded.
The decomposition, and why one number is not enough
Brier = reliability − resolution + uncertainty.
- Uncertainty is a property of the questions, not of you. It is the base-rate variance, and it sets the score you get for saying nothing.
- Reliability (lower is better) is the calibration term: when you said 0.7, did it happen 70% of the time?
- Resolution (higher is better) is the skill term: did you move away from the base rate, and correctly?
The always-say-the-base-rate forecaster has perfect reliability and zero resolution, which is exactly the profile of a system that has learned to be safe rather than useful. The opposite profile — high resolution, poor reliability — is the more common one for an LLM asked for a probability: it discriminates cases well and states the odds too confidently. The two failures need opposite fixes, and a single Brier number tells you neither.
The measurement, in the shape this project can actually run
The agent card already produces the input. One decision row is enough:
| Column | Where it comes from |
|---|---|
p_model |
The forecast the agent acted on |
p_market |
Implied probability from the order book at the same instant |
outcome |
0 or 1, after resolution |
From those three: a reliability diagram, both Brier scores, and their decompositions. The comparison against p_market is the experiment; everything else is diagnostics. And it has an unusual property for a research measurement — it cannot be gamed by picking easier questions, because the baseline gets the same questions.
One honest caveat to state up front: an order book gives a bid-ask spread, not a point probability, and the mid is a convention rather than a truth. On a thin market the spread can be wider than the edge being claimed, so the spread belongs in the log next to the mid — otherwise the comparison silently flatters whichever side of it the agent traded on.
Why this sits in the Future section
It is not a forecasting technique. It is the measurement layer that any probabilistic output needs, and the outputs are multiplying — an LLM asked for a likelihood, a policy's confidence in a grasp, a router deciding whether to escalate. the-harness-not-the-model argues that what you build around a model matters more than the model. Scoring is the part of that harness that tells you whether anything inside it is working, and it is usually the part nobody builds because the model already returns a number that looks like an answer.