Conviction and direction¶
The two most important fields on any per-ticker brief, and the two most commonly misinterpreted. This page explains exactly how they're calibrated and how an AI agent should read them.
The fields¶
Every brief carries:
{
"direction": "neutral", // long_bias | short_bias | neutral | no_signal
"conviction": 0.24, // 0.0 to 1.0
...
}
These come from the direction signal — a deterministic composite computed in novaframe.analytics.analyst.direction_signal, not an LLM judgement. The analyst writes the brief AFTER the direction signal is computed, and the brief is required to be coherent with the signal (gated by validate_brief_against_signal).
What direction means¶
| Value | Reading |
|---|---|
long_bias |
The substrate stack (price, regime, structure, positioning, critical events) leans bullish. The publication thinks the next material move is more likely up than down. |
short_bias |
The substrate stack leans bearish. Next material move more likely down than up. |
neutral |
Substrates conflict or compress; no clear directional lean. Could resolve either way. |
no_signal |
Insufficient data to call. Usually a new ticker, recently halted, or substrate ingest issues. |
neutral is not weak long_bias. A neutral read is an active call that the tape is balanced. It carries information — "wait for resolution before committing" is a valid strategic position.
no_signal is the absence of a call, not a third direction. When you see this, the publication is telling you it doesn't have enough to say anything responsible. Most reasonable agent responses: skip the ticker, retry next cycle.
What conviction means¶
A float from 0.0 to 1.0 expressing the publication's confidence in the directional call — not in the trade idea, not in the price target. It answers: "how strongly does the substrate stack support this direction value?"
Banding¶
| Conviction range | Label | Plain-English read |
|---|---|---|
| 0.0 – 0.20 | minimal | Direction is the slightly-more-likely outcome, but the call is weak. Substrates are noisy or thinly aligned. |
| 0.20 – 0.40 | low | Direction is supported but with significant disagreement across substrates. Treat as soft. |
| 0.40 – 0.60 | moderate | Substrate alignment is reasonable. A typical "we think this matters" conviction. |
| 0.60 – 0.80 | strong | Substrates strongly aligned. The publication is confident in the directional read. |
| 0.80 – 0.95 | very strong | Rare. Multiple substrates flagging the same direction at high intensity. |
| 0.95 – 1.00 | extreme | Almost never seen. Either a major news catalyst with structural follow-through, or a data quality flag (check the brief's data_quality_notes). |
How conviction interacts with direction¶
The combination matters:
| Direction × Conviction | What it means |
|---|---|
long_bias + 0.65 |
"We think this is bullish, with strong substrate alignment." Tradeable read. |
long_bias + 0.18 |
"We think this is bullish, but the call is weak." Informational only. |
neutral + 0.55 |
"We're confident there's no directional lean here." Active call to wait. |
neutral + 0.10 |
"We're not confident there's no lean — substrates conflict and we can't break the tie." Genuine uncertainty. |
short_bias + 0.40 |
"Moderate bearish call." |
no_signal + anything |
The conviction is informational — usually reflects substrate availability, not market confidence. |
Common misreadings to avoid¶
"High conviction means buy" — No. Conviction is about the directional call, not about whether to trade. A neutral brief with conviction 0.75 is a strong "do nothing" signal.
"Conviction values are comparable across tickers" — Mostly yes, but with caveats. The direction signal uses the same composite formula across the universe, so a 0.60 on BTC and a 0.60 on AAVE are calibrated the same way. However, alts often have noisier substrates (thinner orderbook, less consistent regime classification), so conviction values on small-cap alts can be slightly more volatile cycle-to-cycle.
"Conviction will trend" — No. The signal recomputes every cycle from scratch. A ticker can go from conviction 0.55 to 0.20 in the next cycle if the substrate stack shifts. This isn't a bug — it's the system honestly responding to changed conditions.
"Low conviction = wrong" — No. Low conviction means we have less confidence, not we're more likely to be wrong. A low-conviction long_bias that resolved up still counts as the right call. A high-conviction short_bias that resolved up was wrong — and the next cycle will show that resolution in the substrate stack.
How to use these in an agent¶
Pattern 1: Gate decisions on conviction band¶
brief = call_tool("get_ticker_brief", {"ticker": "BTC-USD"})
direction = brief["direction"]
conviction = brief["conviction"]
if direction == "no_signal":
skip_ticker(brief["ticker"], reason="no_signal")
elif conviction < 0.40:
treat_as_informational(brief)
elif conviction >= 0.60:
surface_to_user(brief, framing="high-confidence")
else:
surface_to_user(brief, framing="moderate-confidence")
Pattern 2: Look for cross-substrate corroboration¶
A long_bias brief with conviction 0.55 is more interesting if the get_ticker_sentiment call shows positive sentiment trajectory in the editorial corpus, AND get_ticker_research shows a constructive direction_arc (e.g., conviction rising over the past 48h). Three independent surfaces aligned is structurally meaningful.
Pattern 3: Watch for direction flips¶
If the brief's cross_validation.divergences is empty AND the conviction is rising AND the continuity_diff shows a recent direction change, that's a fresh directional read. Distinct from a stable read that's been at the same direction for cycles.
mar = call_tool("get_active_market_report")
continuity = mar.get("continuity", {})
direction_changes = continuity.get("direction_changes", [])
for change in direction_changes:
if change["ticker"] == my_ticker:
# The publication just changed its mind about this ticker.
# Worth a closer look.
...
Where conviction comes from¶
The composite formula weights price action, regime classification, structural levels, positioning data (funding / OI / L/S ratios), and critical events. Each component contributes a sub-score; the final conviction is a calibrated combination.
For the curious: the formula lives in novaframe.analytics.analyst.direction_signal.compute_direction_signal() and is documented in docs/nep/phase 7 - Direction DDB/direction_signal_spec_v1.md in the analytics repo. The MCP doesn't expose the per-component breakdown — the brief surfaces the composite, not the math, because the math is the publication's IP.
Refresh cadence¶
Conviction values refresh every cycle. The analyst runs every 2 hours (configurable via cycle_interval_hours in the orchestrator), plus a forced cycle at 15:00 UTC ahead of the daily long-form broadcast at 16:00 UTC. So at any moment the data you read is at most ~2 hours stale.
Related¶
- Regime classification — what the
regimefield means and how it interacts with direction - Continuity arc — how cycle-over-cycle changes are surfaced
- Tape-only contract — what the brief is allowed to say
get_ticker_brief— full reference for the brief schema