AQAI QuantAI research lab for systematic strategies

Case study · Backtest

Continuous Macro-Stress Smooth-Score Growth-vs-Defensive ETF Style Allocation

CONTINUOUS_MACRO_STRESS_STYLE_TIMING
etfdailytactical-allocationstyle-timingmacrovolatility-stressgrowth-defensivecontinuous-scoretanh-tiltewma-smoothing

🗓 Backtest period: 2020-01-01..2025-10-08

Jan 2020Total 111.2%Oct 2025
Max DD -31.6%

Backtest metrics

Sharpe
0.92
Total Return
111.2%
Max Drawdown
-31.6%
CAGR
13.9%
Volatility
21.1%
Beta vs SPY
0.76
Trades
13,932

Strategy Card

Continuous Macro-Stress Smooth-Score Growth-vs-Defensive ETF Style Allocation — strategy card

Spec ID: spec-continuous-macro-stress-style-timing-us-etfs-1786122720 · Generated: 2026-08-07 17:54 UTC

Cluster: Tactical Allocation · Sub Cluster: Macro-Stress Growth Defensive Etf Timing

One-line description

Dynamically tilts a U.S. ETF portfolio between growth/technology and defensive/value-income baskets using a continuous macro-stress score built from rates, equity drawdown, VIX regime, VIX relief, and recent growth extension. The score is transformed through a tanh tilt and EWMA-smoothed before rebalancing.

Why this trade exists

The trade expresses the idea that growth-vs-defensive leadership is partly state-dependent. Falling long rates, equity drawdown relief, and volatility stress relief can improve the relative payoff to long-duration growth assets, while crowded growth performance in low-volatility/rate-quiet regimes can make defensive/value-income exposure more attractive.

The strategy does not forecast single-name alpha. It rotates between diversified ETF style baskets, aiming to capture broad regime changes while avoiding binary all-in/all-out timing through continuous scoring and slow weight smoothing.

Algorithm

[code omitted from public view]

Parameters

Param Value Notes
Strategy variant Main selected smooth-score policy No optional bond/credit overlay.
Growth basket QQQ, XLK, VGT, SPYG, VUG Equal-weight within basket.
Defensive basket SCHD, VYM, VTV, FDVV, COWZ Equal-weight within basket.
Signal-only ETF SPY Used for drawdown feature; not part of traded basket in the target allocation.
Macro inputs DGS10, VIX 10Y yield and volatility regime/relief inputs.
Backtest window 2020-01-01 to 2025-10-08 Daily bars.
alpha 0.50 Blend between rate relief and SPY drawdown core score.
lambda_s 0.50 Weight on stress interaction score.
lambda_c 0.05 Penalty on crowded growth/low-volatility score.
MaxTilt 0.50 Growth weight range is theoretically 0% to 100% before any platform position caps.
tau_w 0.75 Tanh score-temperature for target weight.
eta 0.05 EWMA smoothing speed for actual growth weight.
softplus_tau 1.00 Softplus smoothing parameter.
Rebalance Daily close Continuous target update and close rebalance convention.
Trading cost assumption 10 bps paper turnover-cost parameter; platform costs include $0.004/share commission, $1 minimum, 1% max commission, 0 bps slippage The code notes cost_bps is parsed for paper fidelity and may not be applied as explicit trade slippage/commission in generated orders.
Price policy Real ETF closes for execution Short missing signal gaps may be forward-filled for analysis features only, not for execution prices.

Look-ahead audit

# Concern Status
1 Close-derived ETF, SPY, VIX, and DGS10 features Uses information through the signal date only; no future returns are required for feature construction.
2 Execution timing Rebalances at the close under the platform close/MOC convention; no same-day open execution from same-day close signals is specified.
3 Expanding z-scores and running peaks Expanding calculations are causal and initialized with available warmup history only.
4 Macro data availability DGS10 uses an observation-date point-in-time filter; release-time lag risk remains if the database timestamp is only date-level.
5 Missing prices Forward-fill is limited to analysis signal construction; execution prices must be real closes or trades are skipped.

Caveats / known limitations

Results

The backtest produced a positive total return of 111.24% with Sharpe 0.92, Sortino 1.20, and beta to SPY of 0.76. Drawdown control was broadly in line with the paper-style objective, with max drawdown of -31.61%, but realized volatility was still equity-like at 21.08%. The high win rate and profit factor are favorable diagnostics, while the 13,932 trades highlight meaningful implementation and cost sensitivity.

Run diagnostics

Recomputed here from the run's stored daily returns, because every annualized figure in the table above is derived from the LENGTH of that array (years = n / 252). Only total return and max drawdown do not depend on the row count, so when the recomputed and stored values differ by a common factor, those two are the numbers to trust.

Check From the run's own returns Note
Daily-return rows 1,450 1.00x the 1,454 trading days in 2020-01-01..2025-10-08
Distinct dates 1,450 one row per date
Date span 2020-01-02 .. 2025-10-08
Sum of daily returns 111.24% matches the reported total return
Sharpe from these rows 0.92 stored 0.92
Volatility from these rows 21.08% stored 21.08%
Max drawdown from these rows -31.61% stored -31.61%
CAGR from these rows 13.88% stored 13.88%

Backtest metrics snapshot

Metric Value
Total Return 111.24%
Sharpe 0.92
Sortino 1.20
Calmar 0.44
Max Drawdown -31.61%
Volatility 21.08%
Beta vs SPY 0.76
Win Rate 83.00%
Profit Factor 11.83
Total Trades 13932
Symbols 11 (COWZ, FDVV, QQQ, SCHD, SPY, SPYG, VGT, VTV, VUG, VYM, +1 more)