# Momentum-sleeve volatility-target overlay (H2) — Design

**Status:** ❌ FALSIFIED — do NOT implement (2026-07-07)
**Date:** 2026-07-07

## FALSIFICATION VERDICT (2026-07-07)

Running this spec's own gate 2 (anti-pro-cyclical) EARLY — before any build — killed it. The
headline +0.24 OOS book Sharpe is **not a return edge; it is pure volatility-shrinkage from
de-risking, and the de-risking is pro-cyclical** (the exact rejected-controller failure mode,
[[pearl_fxhnt_reactive_risk_controllers_rejected]]):

- **Return contribution is negative and insignificant:** daily book-return difference
  (vol-targeted − raw) = **−0.31 bp/day, t = −0.65**. The overlay earns *less*, not more; Sharpe
  rises only because vol falls faster than return (de-leveraging, not alpha).
- **It misses more upside than downside it avoids:** exposure removed on down days avoided 99.4%
  of loss, but removed on up days missed 110.3% of gain → **net −10.8% return drag** from the
  de-risking itself.
- **It cuts hardest right before the biggest up days:** mean scale the day before a top-decile up
  day = **0.854 vs 0.904 unconditional** — the "cut before the bounce" signature.

Root cause the design missed: in crypto-bull, high realized vol and drawdown-then-bounce are
strongly correlated, so conditioning on **vol** ≈ conditioning on **drawdown** *in effect* — the
overlay is the 3×-rejected reactive de-sizing in a new guise, not a distinct mechanism. The
modest maxDD improvement (−6.7→−5.3) is bought with a regime-fragile (bull-only sample, no 2022
bear), return-insignificant, pro-cyclical mechanism → for real capital this is a false-PASS risk.
**Verdict: not built. Raw momentum stands. See [[pearl_fxhnt_voltarget_overlay_is_reactive_desizing_rejected]].**

The design below is retained as the falsified record (what was proposed and why it was rejected).

---

## Goal

Add an **ex-ante, de-risk-only sleeve-level volatility-target overlay** to the crypto momentum
sleeve (`crypto_tstrend`, driven by `TrendRunner`), scaling the whole position vector down in
high-realized-volatility regimes and never levering up. This raises the risk-adjusted return of
the sleeve — and thereby the naive `bybit_4edge` book — without adding leverage, funding cost, or
meaningful turnover cost. Deploy only if the improvement survives on the fully net-of-cost book
and clears an explicit anti-pro-cyclical falsification gate.

## Why (the investigation)

Investigation-first, out-of-fold (expanding window, min 250d train, 21d step, 881 OOS test days,
2023-01 → 2026-07), measured on the exact 4-sleeve deploy book (tstrend/positioning/unlock/xsfunding)
using persisted per-sleeve daily returns (`bybit_sleeve_ret`):

| Momentum variant | CAGR | Sharpe | maxDD |
|---|---|---|---|
| raw (current) | 77.0% | 3.68 | −6.7% |
| **de-risk-only vol-target (cap 1.0)** | 75.4% | **3.92 (+0.24)** | **−5.3%** |
| leveraged Pareto (cap 1.5, ref) | 79.4% | 3.80 (+0.12) | −5.7% |

Key findings:

1. **The free (defensive) half wins.** Scaling exposure *down* in high-vol regimes (`cap=1.0`,
   never lever) delivered a **larger** Sharpe gain (+0.24) than the leveraged version (+0.12).
   Levering up in calm regimes adds vol-adjusted return but also risk, diluting the Sharpe.
2. **Net-of-cost robust.** The overlay adds only ~0.62% |Δscale|/day (the 40-day trailing vol
   moves slowly). Charging the incremental rebalance turnover at 10/15/25/40 bp leaves the gain at
   +0.24 / +0.23 / +0.23 / +0.22 Sharpe — above the 0.2 kill-gate even at an absurd 40 bp/turn.
3. **Parameter-robust, not fit.** L ∈ {20, 40} and floor ∈ {0.25, 0.5} all give ~+0.24 Sharpe and
   the same DD improvement — the effect is structural (momentum vol clustering), not a lucky pick.
4. **Not redundant with per-symbol vol targeting.** `TrendRunner` already vol-targets each symbol
   cross-sectionally; the sleeve overlay responds to the sleeve's *realized* return vol, which
   carries the correlation/regime vol that per-symbol targeting cannot see.

Falsified alternatives from the same investigation (do NOT revisit): **H1** — ex-ante sleeve
re-weighting (Sharpe/inverse-vol) fails its gate (equal-weight is at the efficient point; tilting
costs CAGR). **H3** — `xvenue_carry` is vestigial (~0 return; dilutes CAGR) → separate cleanup spec.

## The load-bearing distinction: this is NOT the rejected reactive de-sizing

[[pearl_fxhnt_reactive_risk_controllers_rejected]]: reactive de-sizing was A/B-rejected 3× as
pro-cyclical (it cut after drawdowns and got whipsawed — cut at the bottom, missed the bounce).
This overlay is different in kind, and the difference is load-bearing:

- **Rejected:** conditioned on **drawdown / recent PnL** — path-dependent, sticky, directional.
- **This:** conditions on **realized volatility** — direction-agnostic, mean-reverting, symmetric.
  High vol ≠ recent loss.
- **Empirical proof it is not the trap:** it *improves* maxDD (−6.7 → −5.3) and Sharpe across all
  folds and params. The rejected controllers did the opposite (net worse). Same failure mode →
  same signature; this shows the inverse signature.

Because this is real capital and the pattern superficially resembles the rejected one, the spec
mandates an **explicit anti-pro-cyclical falsification gate** (below) before any deploy.

## Design

### The overlay (inside `TrendRunner`)

Add two optional kwargs to `TrendRunner.__init__`: `sleeve_vol_target: float | None = None`
(annualized; `None` = current behaviour, overlay off) and `sleeve_vol_window: int = 40`, plus a
`sleeve_vol_floor: float = 0.25`. When `sleeve_vol_target` is set, `run()`:

1. Forms the gross-capped `pos` for day `d` exactly as today (`_positions_for_day`).
2. Books the **raw** realized return `raw_r` for `[d, nxt]` (price + funding, cost-free) — the
   unscaled sleeve return.
3. Computes `scale[nxt] = clip(sleeve_vol_target_daily / trailing_vol, sleeve_vol_floor, 1.0)`
   where `trailing_vol` = realized daily vol of the **raw** booked returns over the last
   `sleeve_vol_window` days strictly BEFORE `nxt` (no lookahead; empty/short buffer → scale 1.0).
4. Books the scaled return: `scale[nxt] · raw_r` and computes turnover on the **scaled** position
   vector `scale[nxt] · pos` versus the previous day's scaled positions — so the vol-target's
   own rebalance turnover flows through the existing `turnover` haircut automatically (faithful
   net-of-cost; no separate cost path).

Using the **raw** (unscaled) returns for `trailing_vol` breaks the feedback loop (scale depends
only on the underlying strategy's vol, not on the already-de-risked vol) and matches the
investigation's measurement exactly.

### `sleeve_vol_target` is adaptive, not a tuned constant

Per [[feedback_adaptive_not_tuned]] and [[feedback_isv_for_adaptive_bounds]], `sleeve_vol_target`
is **not** a hand-picked number. The deploy wiring sets it to the **expanding-window realized daily
vol of the raw sleeve returns** (the sleeve's own long-run vol, growing with data), so the ratio
`target/trailing` is ≈1 on average and deviates only in vol regimes. `sleeve_vol_window` (40) and
`sleeve_vol_floor` (0.25) are held at values shown robust across the tested range — the plan pins a
robustness check (the metric must not degrade materially at L=20 or floor=0.5), so they are chosen
for stability, not to maximise the backtest number.

### SSOT: `run()` and `weights_and_contributions()`

`weights_and_contributions()` (which feeds `sleeve_returns_from_store` → the persisted sleeve
returns → the book combine) must apply the **same** `scale` series so persisted returns match
`run()`. Both iterate the same `all_days` deterministically; factor the scale computation so both
share one source of truth (a private helper that, given the raw-return buffer, returns the per-day
scale) — no drift between the booked return and the surfaced weights, matching the existing
invariant that `Σ weight·return == run()`'s booked gross return.

### Deploy: back-compute + swap (deterministic → no separate shadow wait)

The momentum sleeve is **warehouse-backed and deterministic** — its returns are a pure function of
the price/funding data already stored. Unlike the `xsfunding` live-snapshot track (which could not
backfill a missed past day), the vol-targeted momentum sleeve can be **back-computed over both the
historical backtest and the already-elapsed forward window** ([[reference_fxhnt_forward_gate_two_store_sync]]:
warehouse-backed tracks recompute from persistent data; live-snapshot tracks cannot). So a separate
2–3-week shadow-observation wait is unnecessary and is NOT used. Instead:

1. Back-compute the vol-targeted momentum sleeve + the `bybit_4edge` book over the backtest **and**
   the elapsed forward window (the ~16 nights `crypto_tstrend` already has). Run gates 1–3 on that.
2. If all gates pass, swap the vol-targeted sleeve into the deploy `bybit_4edge` book. This changes
   the book's return definition → it **re-inceptions** (`15/21` → `0/21`), and the book's own
   21-day reconciliation gate becomes the frozen-forward validation of the new definition. No
   separate `_voltgt` shadow track is created — the book's existing gate polices it.

This is equally gated (the book gate validates the swapped-in definition over unseen nights either
way) but ~2–3 weeks faster than a separate shadow, because determinism lets the elapsed-forward
reconciliation stand in for a fresh shadow observation. Resetting `15/21`→`0/21` is the honest cost
of a definition change (the old 15 nights observed a different book); shadow-first would incur the
same reset, only later.

## Validation gates (all must pass before the swap into the deploy book)

1. **Net-book re-measure — multi-condition (not a single Sharpe point).** Build the overlay in
   `TrendRunner`; re-run the real `bybit_4edge` backtest with the full 5.5 bp net cost model (not
   the pre-cost sleeve stream), over the historical backtest **and** the elapsed forward window.
   Deploy only if ALL hold: net book Sharpe improves by **≥ +0.15** (the pre-cost +0.24 will
   compress net — a brittle +0.2 point-gate risks false-killing a real edge), **maxDD does not
   worsen**, gate 3 (per-year consistency) passes, and gate 2 (anti-pro-cyclical) is clean. The
   rigor lives in the robustness conditions — hard to fake — not in a single number a fluke could
   clear. If the net improvement is below +0.15 or DD worsens, H2 is killed; raw momentum stands.
2. **Anti-pro-cyclical falsification gate.** Test the specific rejected failure mode: the overlay
   must NOT systematically cut exposure just before the momentum sleeve's best recovery days.
   Concretely — condition scale on next-day sleeve return; the mean scale ahead of the top-decile
   positive return days must not be materially below the unconditional mean scale (the rejected
   controllers failed exactly here). Fail → do not deploy.
3. **Per-year / per-fold consistency.** The Sharpe/DD improvement must hold in a majority of
   calendar years (not driven by one regime). A single-year artifact fails.
4. **Full suite green** + a new invariant test: with `sleeve_vol_target=None`, `run()` and
   `weights_and_contributions()` are byte-identical to today (backward compat); with it set,
   `Σ weight·return == run()`'s booked gross return still holds day-by-day.

## Non-goals

- No leverage / offensive scaling (`cap` is fixed at 1.0 — the whole point is the free defensive
  half). The leveraged Pareto variant is explicitly out of scope.
- No sleeve re-weighting (H1, falsified). No `xvenue_carry` changes (H3, separate spec).
- No change to the per-symbol vol targeting or `gross_cap` already in `TrendRunner`.
- No adaptive/CVaR book overlay (that is the dormant Phase-2, not this).

## Risks

- **Pre-cost → net gap.** The +0.24 was on pre-cost sleeve returns; the net-book re-measure
  (gate 1) is the real test. If costs on the actual book erode it below +0.2, we stop.
- **Regime dependence.** 3.5 years OOS spans a bull-heavy crypto period; gate 3 (per-year) guards
  against a single-regime artifact, but the re-inceptioned `bybit_4edge` book's own 21-day forward
  gate (post-swap) is the ultimate arbiter before capital.
- **Resemblance to the rejected pattern.** Mitigated by gate 2, but reviewers must treat any sign
  of pro-cyclical cutting as a hard stop, not a tuning problem.
