Apex Rotation with volatility controls: specification

A momentum rotation into the 4 strongest S&P 500 / Nasdaq-100 stocks, sized to a 50% volatility target, plus a 0.5x equity TQQQ sleeve. The sleeve is held only while QQQ's 20-day volatility is low. Account: US margin account at Interactive Brokers.

Data

ItemSource
Stock pricesDaily open, high, low, close, adjusted for splits and dividends (total return)
UniversePoint-in-time S&P 500 and Nasdaq-100 membership (constituents as of each date, including later-delisted names)
Market capPoint-in-time company market cap (all share classes)
QQQ, TQQQDaily total-return open, high, low, close
Fed fundsEffective federal funds rate (FRED DFF)
Period2010-02-11 (first TQQQ session) to 2026-09-18

Account and costs

Timing

ItemDecided onTrades at
Stock sleeve picks, weights, vol scaleclose of day t-1open of day t
Stock sleeve rebalanceevery 20 sessions per sleeveopen
TQQQ vol gateevery session, close of day t-1open of day t, the session after it flips
TQQQ resize to 0.5 x equity while on11th session of each monthopen

Rules

STOCK BOOK: 4 sleeves, each 1/4 of equity
  Sleeve k (k = 0..3) rebalances on sessions 5k, 5k+20, 5k+40, ...
  counted from 2010-02-11 (session 0).

  On a sleeve's rebalance, using data through the prior close:
    universe = point-in-time S&P 500 + Nasdaq-100 members; one share
               class per company (the higher-ranked class)
    eligible = close > SMA200 and SMA200 > its value 20 sessions earlier
    rank     = EMA50 / EMA200 of the close, highest first, eligible names only
    picks    = keep each name the sleeve already holds while it is eligible
               and ranked 12 or better; fill the remaining slots, up to 4
               names, with the highest-ranked eligible names not yet held
    w_i      = cap_i^1.5 / sum of cap^1.5 over the picks
               (cap = point-in-time company market cap)
    basket_vol = sample stdev (ddof 1) of the last 20 daily returns of the
                 portfolio sum(w_i * r_i), annualized x sqrt(252)
                 (r = simple daily total returns of the picks)
    scale    = clip(0.50 / basket_vol, 0.0, 1.5)
    target_i = (equity at today's open / 4) * w_i * scale
  Between rebalances, sleeve positions are not traded (they drift).

TQQQ SLEEVE
  qqq_vol = sample stdev (ddof 1) of the last 20 daily QQQ total returns
            x sqrt(252), on the prior close
  gate starts ON
  if ON  and qqq_vol > 0.32: OFF -> sell all TQQQ at the open
  if OFF and qqq_vol < 0.28: ON  -> buy TQQQ to 0.50 x equity at the open
  (between 0.28 and 0.32 the gate keeps its state)
  While ON, also trade TQQQ to 0.50 x equity on the 11th session of
  each month.

CASH
  cash = equity - stocks - TQQQ. Negative cash is a margin loan.
  Maximum gross exposure 2.0x equity (1.5 stocks + 0.5 TQQQ).

DELISTING
  A held stock with no price on a session is converted to cash at its
  last close.

Margin model (IBKR Reg T with concentration stress)

maintenance = max( 0.25 x stock value + 0.75 x TQQQ value,
                   div(n) x sum_i stress_i x stock_value_i )
  n        = number of distinct companies held
  div(n)   = 1.00 for n <= 2, 0.95 for 3-5, 0.75 for 6-9, 0.60 for 10+
  stress_i = min(1, max(0.30,
                        0.30 + 0.065 x max(0, ret1y_i - 0.50),
                        0.50 x vol30_i))
  ret1y_i  = 252-session total return
  vol30_i  = population stdev (ddof 0) of the last 30 daily log returns x sqrt(252)

initial margin on any purchase:
  equity >= max(0.50 x long market value, maintenance rule sum, 1.1 x stress term)
  after the trade; purchases are scaled down pro rata to satisfy it.

maintenance check: at every close, and at the daily lows (all positions
marked at their low). A deficit is a breach: at the next open, sell all
positions pro rata until equity >= 1.10 x maintenance.

Required outputs for comparison

Report these, computed independently:

  1. Gate switch list: decision date, trade date, new state.
  2. Picks with weights for each sleeve on its first rebalance on or after each Jan 2 from 2011 to 2026.
  3. Calendar-year returns, 2010 to 2026.
  4. CAGR, maximum drawdown (with peak and trough dates), and every margin breach date.
  5. Rolling 4-year CAGR windows starting on the first session of each month from 2010-03 to 2022-09: mean, median and worst.