Convexity Score · v3.3

One number for“what’s the model’s call?”

The model's call on a stock's next 180 days, as one number. Six features roll into a nightly forecast for large caps above the $25B coverage floor. The methodology is open, caveats included, and every published vintage is scored against what the market actually did. Same input, same output, every user, every session.

SCORE DRIVERS · NVDAsix features, signed contribution to the composite
Price momentum 12-1
+0.061
Revenue growth acceleration
+0.054
Smart money composite
+0.039
Insider net flow
−0.025
Low-vol beta
−0.018
Literal gamma (monthly)
+0.012
6features
180dforward horizon
$25Bcoverage floor
liverealized-IC record

Live scoreboard

Eight names. Same window. Driver chips, not just rankings.

NIGHTLY · computed 2026-07-21
  1. 01NVDA87pct+momentum+rev growth+smart money
  2. 02META76pct+momentum+smart money+rev growth
  3. 03MSFT71pct+momentum+smart moneygamma
  4. 04AAPL62pct+smart moneyrev growth+momentum
  5. 05GOOG56pct+momentuminsider flow+rev growth
  6. 06TSLA44pct+rev growthlow-vol betagamma
  7. 07BA18pctinsider flowmomentumsmart money
  8. 08INTC9pctmomentumrev growthsmart money

Same nightly run, same universe gate (S&P 500 ≥ $25B), same coefficients. Sorted by predicted forward-return rank. Each row's three chips are the features that mattered most for that ticker's prediction.

It's a Ridge composite of six measured signals.

The score is a regularized linear regression (Ridge) trained on a rolling window of historical data. The training target is the 180-trading-day sector-neutralized log forward return. Inference produces a raw prediction per ticker, rank-transformed within the day's cross-section to a 0–100 percentile.

The six features

  • price_momentum_12_1+ expected sign12-1 log return, panel-derived
  • insider_net_flow− expected signSEC Form 4 buys minus sells, trailing 60-90d
  • smart_money_composite+ expected sign13F whales + STOCK Act + 13D/G + Form 144
  • low_vol_beta− expected sign252d OLS beta vs SPY (low-vol anomaly)
  • literal_gamma_monthly~ mixed priorMonthly quadratic regression coefficient on r²
  • revenue_growth_acceleration+ expected signQuarter-over-quarter delta in revenue growth rate

Dropped during empirical validation: analyst_revisions (regime-flip risk, pooled t −0.641); earnings_surprise_drift (data not on plan); fcf_margin_momentum (−0.010 IC); net_debt_change_yoy (neutral).

Walk-forward validation · and its limits

Six quarterly folds. One bad fold. And the caveats, in writing.

Each fold trains on prior data and validates on a held-out forward quarter. The information coefficient (IC) is the Spearman rank correlation between predicted and realized 180-day returns. The 2025-06 fold was the regime-shock fold (SPY 60d annualized vol ~33%) and the empirical motivation for the v3.1 regime gate.

Read this chart with its limits: the six folds' forward windows overlap (so conventional significance statistics overstate confidence), the universe is today's surviving roster, and our own deeper testing – a 20-year panel and a fully point-in-time factor study – found the price-action half of the model is approximately zero and standard large-cap factors don't survive survivorship correction. We publish those findings in the methodology instead of quoting the backtest as proof. The number that should convince you is the live realized-IC record: every published vintage is immutable, and its actual forward IC is recorded as each window matures – never revised, never backfilled.

−0.20−0.100+0.10+0.20
2024-03
+0.144
2024-06
+0.156
2024-09
+0.131
2024-12
+0.085
2025-03
+0.131
2025-06
−0.111regime shock
median +0.131 (v3.0 anchor run)six overlapping folds – a small-sample estimate with documented biases, not proof; judge the score by its live record

Where it works, where it doesn't

The score is gated at $25B market cap. Here's the honest why.

An earlier version of this page showed a cap-quintile IC table as the floor's evidence: predictive power looked monotonic in cap size, with small caps anti-predictive. When we re-labeled that test with point-in-time market caps, most of the gradient turned out to be a look-ahead labeling artifact – so we retracted the table rather than keep marketing it.

The floor stays for a reason that did survive scrutiny: the model's highest-weight inputs are filing-driven alt-data with ~74% coverage above $25B that collapses on smaller names. Below the floor, a score would be mostly imputation dressed as data. So sub-floor names return below_cap_floor instead of a number we can't stand behind – and route to the surface that does cover them.

≥ $25BConvexity Score180-day forward-return forecast (this page)
$10B – $25BQuality Profiledescriptive quality benchmark, explicitly not a forecast
$5B – $10Bnot yet covereda known gap, listed as such; not a data bug
$300M – $5BValue+QualityIC-supported small/mid ranking, presented as a ranking, not proven alpha

Every cap band gets the commitment we can actually defend: a forecast where the inputs exist, a descriptive benchmark or a ranking where they don't, and an explicit gap where we have nothing yet. The ticker page routes below-floor names to their module score automatically.

The nightly run

One job. Pinned cron. Walk-forward train, then predict.

  1. 03:00:00

    ARQ cron fires

    sync_convexity_scores kicks off. Skipped if CONVEXITY_SYNC_ENABLED is false.

  2. 03:00:14

    Panel fetch + universe gate

    Five years of adjusted closes pulled via FMP for the coverage universe (S&P 500 + the broader large-cap roster + tracked and watchlisted names) plus benchmarks. Names below $25B are excluded from inference.

  3. 03:00:48

    Walk-forward train + production fit

    8 quarterly as-ofs → 6 validation folds → production Ridge fit on the full window. Coefficients and the training scaler are persisted to convexity_alpha_runs.

  4. 03:01:22

    Regime gate + inference

    If SPY 60d annualized vol ≥ 20%, the gate fires and scoring is suppressed for the night. Otherwise: six features computed per ticker, z-scored against the training scaler, multiplied by the persisted coefficients.

  5. 03:01:56

    Rank-map + store

    Raw predictions rank-mapped to 0–100 percentiles within today's universe. Rows written to convexity_scores with formula_version=v3.3. Freshness badge ticks to “healthy.”

Programmatic

Public v1 API.
DataEnvelope shape.

Same freshness contract as quotes and fundamentals: data plus meta, with the score's exact compute timestamp. The response carries the rank-mapped percentile, the raw prediction, and the six feature values used for inference. Below-floor tickers return status=below_cap_floor; gated-regime nights return regime_gate_active=true.

Read the API reference →

  curl · v1/convexity-score
$ curl https://api.convexity.os/v1/convexity-score/NVDA \
  -H "Authorization: Bearer $CONVEXITY_KEY"

# 200 OK · 47ms
{
  "data": {
    "ticker": "NVDA",
    "formula_version": "v3.3",
    "ridge_score": 0.123,
    "ridge_score_pct": 87,
    "window_days": 180,
    "feature_values": {
      "price_momentum_12_1": 0.412,
      "revenue_growth_acceleration": 0.107,
      "smart_money_composite": 0.829,
      "insider_net_flow": -0.042,
      "low_vol_beta": 1.604,
      "literal_gamma_monthly": 0.018
    },
    "sector_etf": "XLK",
    "sector_rank": 3
  },
  "meta": {
    "data_as_of": "2026-07-21T03:01:56Z",
    "sync_status": "healthy",
    "source": "convexity",
    "regime_gate_active": false,
    "walk_forward_median_ic": 0.131
  }
}

What about

The edge cases we get asked about.

How do I know whether the score actually works?

Watch its record, not our backtest. Every published score vintage is immutable; as each forward window matures (21, 63, 126, 180 trading days) we record the realized rank IC of the scores we actually published against the returns that actually happened, and publish every measurement on the methodology page and via GET /api/convexity-score/realized-ic. Rows are computed once and never revised. The first v3 vintages (2026-05-26) began maturing in late June 2026, and the realized-IC record extends as each forward window closes.

What about names below the $25B floor?

They return a null ridge_score with status=below_cap_floor, and the ticker page routes them to the surface that does cover them: Quality Profile (≥$10B, descriptive) or the Value+Quality ranking ($300M–$5B). The floor exists because the model's alt-data inputs lose coverage below it – a sub-floor "score" would be mostly cross-section imputation, and we'd rather show the right surface than a misleading number.

What is the walk-forward IC actually telling me?

Information coefficient is the rank correlation between predicted and realized 180-day forward returns, measured across the universe at each fold. The honest reading: it is a small-sample estimate from six folds whose forward windows overlap, on a survivors-only universe – so it overstates confidence, and our deeper point-in-time research (published in the methodology) found large-cap factor signals generally do not survive survivorship correction. We show the chart with those caveats attached and let the live realized-IC record be the proof, in either direction.

When does the regime gate fire?

When SPY trailing-60-day annualized realized volatility crosses 20%. The threshold sits about 3 sigma above the long-run good-regime mean (~12%) and was calibrated against the worst historical fold (2025-06 at 33% annualized vol). On gated nights no new scores are written; the envelope returns regime_gate_active=true, and the ticker page shows the last pre-pause prediction with an explicit “Model paused – showing last prediction (stale)” banner. Stale scores are never dressed up as fresh ones.

Why these six features and not others?

Empirical validation. We sampled a wider candidate set, walked each forward across 6 quarterly folds, and kept the ones that lifted IC without flipping sign across regimes. analyst_revisions got dropped for regime-flip risk; fcf_margin_momentum hurt IC by ~0.010; net_debt_change_yoy was neutral. The six that shipped are the ones that survived.

Why a 180-day forward horizon?

We swept horizons (60d, 90d, 120d, 180d, 252d). 180d is the IC optimum – shorter horizons get dominated by noise + mean-reversion, longer horizons dilute the signal with regime drift. The training target is 180-trading-day sector-neutralized log forward return; the score is naturally relative to GICS-sector peers without an explicit sector flavor knob.

What's the kill switch for?

If the upstream price feed degrades mid-window or we detect a data-quality regression, we'd rather hold the last-known-good scores than recompute on bad inputs. CONVEXITY_SYNC_ENABLED=false halts the next run without a deploy.

One forecast, honestly computed, on every name we trust it on.

In the product from your first session. Methodology open. API gated by tier.

Founder pricing holds for life while the waitlist is open.