Skip to content

What (One-liner)

Three-in-one market criticality heuristic: rising correlation × volatility suppression × heavy-tail regression → weighted fragility score [0, 1]. Self-declared 'not production risk model', used as a Canvas market state visual indicator.

How to use

Drag b0_criticality_v1 onto Canvas, connect upstream to price_factor_v1 node (Canvas automatically converts to returns), optionally manually fill correlations matrix. Typical usage:

price_factor → b0_criticality_v1 (returns auto) → reflexivity_detector_v1

                        (multi-asset) correlations → cross-asset fragility overlay

Core formulas

# Three independent gated components:
avg_corr  = mean(upper_tri(correlations))         if len >= 2
vol       = std(returns) * sqrt(252)              if len > 10
suppr     = 1 - min(1, vol / (max|r|*sqrt(252)+1e-9))
tail_α    = -slope(log(rank) vs log(sort_desc(top-10%|r|)))  if tail > 5

# Weighted composite (capped 1.0):
fragility = 0.40 * max(0, avg_corr)
          + 0.35 * suppr
          + 0.25 * min(1, tail_α / 5.0)
          |> min(1.0, _) |> round(4)

Rounding contract: All numeric fields round(4); fragility strictly [0, 1].

Gating contract: When inputs do not meet thresholds, corresponding fields are entirely missing (not None).

Assumptions & applicability

Assumptions: Daily frequency (sqrt(252) annualization) + symmetric correlation matrix + ad-hoc subset weights + tail log-rank approximation.

Applicable: Canvas market criticality visual indicator, educational demo, cross-asset fragility overlay input.

Not applicable: Production-grade VaR, intraday, Hill-level tail exponent estimation, ≤10 observations, monthly/weekly frequency.

Input / Output contract

{returns?, correlations?}{_method, fragility_composite_0_1 (always), avg_pairwise_correlation?, realized_vol_annualized?, vol_suppression_index_0_1?, tail_decay_exponent_proxy?}. gated fields missing when input insufficient.

Known limitations

  1. Self-declared heuristic: _method field explicitly states 'not production risk model'
  2. Suppression uses whole-sample max (field name "rolling_max" is misleading — not truly rolling)
  3. Tail α uses naive log-rank regression (Hill MLE not implemented)
  4. Weights 0.40 / 0.35 / 0.25 ad-hoc (no empirical calibration)
  5. sqrt(252) hardcoded (systematic bias for non-daily frequency inputs)
  6. Correlation matrix PSD / symmetry not validated
  7. Gated fields missing (not None): clients must handle gracefully with if 'field' in result:
  8. n=1 corr → avg_pairwise_correlation field does not appear
  9. len(returns) ≤ 10 → vol / suppression / tail fields all missing

References

Scheffer et al. (2009) Early-warning signals for critical transitions (Nature) + Preis et al. (2012) Correlations under stress (Sci Reports) + Clauset-Shalizi-Newman (2009) Power-law distributions (SIAM Review). See frontmatter for details.

Golden Test

tests/golden/fixtures/tier3/b0_criticality/, numpy_manual cross-implementation (reference_compute.py independent numpy re-implementation + mutual assertion with b0_6_criticality at capture time). 1e-10 tolerance. 11 tests:

  • matches_snapshot — 6 cases (fragile / benign / returns-only / too-few / n=1 corr / no-input) byte-equal
  • determinism — 5 reruns consistent
  • avg_corr_upper_triangular_mean — 3x3 matrix known off-diagonal → 0.6 exact
  • n_equals_one_no_avg_corr — [[1.0]] → avg_pairwise_correlation field missing
  • returns_too_short — len=10 → vol / suppression fields missing
  • returns_eleven_activates_branches — len=11 boundary
  • fragility_composite_bounded_0_1 — extreme inputs all within [0, 1]
  • no_inputs_returns_zero_fragility — all None → fragility = 0.0
  • method_field_locked_method always carries heuristic declaration
  • rounding_contract — all numeric fields round(4)
  • weight_contract — known avg_corr=0.85 → fragility = 0.34 exact (weight 0.40 locked)

Changelog

  • 1.0.0 (2026-04-20) — First Active (Tier 3 batch 1.2, cross-impl numpy_manual)

Verifiable intelligence for the decisions that demand scrutiny.