Case study · Backtest
🗓 Backtest period: 2020-01-01..2024-07-01
Spec ID: spec-benchmark-relative-drawdown-targeted-kelly-spy-gld-1789724600 · Generated: 2026-09-18 10:19 UTC
Cluster: Kelly Allocation · Sub Cluster: Spy-Relative Drawdown-Targeted Constrained Overlay
Daily estimates a constrained Kelly allocation across SPY and GLD, then scales its active deviation from a 100% SPY benchmark to prescribed drawdown-risk targets. Infeasible rebalances are skipped rather than clipped or partially executed.
The strategy seeks to capture time-varying growth opportunities in equities and gold while controlling how far the portfolio departs from SPY. For target relative drawdown risk R, the paper maps risk to a Kelly loading k = 2R / (1 + R) and constructs w = u + k(w_star - u), where u is the SPY benchmark and w_star is an estimated Kelly portfolio.
Economically, SPY and GLD can offer changing expected returns and diversification benefits. Fractional Kelly sizing reduces sensitivity to noisy mean and covariance estimates, while gross-leverage, volatility, active-position, turnover, and bankruptcy constraints limit implementation risk. Because those constraints, estimation error, discrete trading, and charged commissions depart from the source paper's frictionless setting, its exact optimality and drawdown identities serve only as theoretical benchmarks.
[code omitted from public view]
| Param | Value | Notes |
|---|---|---|
| Rule type | BENCHMARK_RELATIVE_DRAWDOWN_TARGETED_KELLY |
Benchmark-relative fractional Kelly overlay |
| Universe | SPY&US&ETF, GLD&US&ETF |
Two US ETFs; SPY is the benchmark |
| Benchmark vector | SPY 1.0, GLD 0.0 |
Prescribed benchmark anchor |
| Cash asset | Implicit zero-return bank account | w_cash = 1 - sum(w_risky) |
| Return input | Adjusted-close log returns | log(close_t / close_{t-1}); winsorization disabled |
| Rolling window | 252 trading days | Requires 252 complete paired observations |
| Annualization | 252 | Applied to estimated means and covariance |
| Covariance regularization | 20% diagonal shrinkage; 0.000001 * I jitter |
0.8 V_sample + 0.2 diag(diag(V_sample)) + 0.000001 I |
| Drawdown-risk targets | R = 1/7, 1/3, 3/5 |
Evaluated across the leverage scenarios |
| Kelly multipliers | k = 1/4, 1/2, 3/4 |
From k = 2R / (1 + R) |
| Gross-leverage scenarios | 1.0, 2.0, 4.0 |
Intended comparison grid; framework maximum is 4.0 |
| Kelly numerical bounds | [-4.0, 4.0] per risky asset |
Bounds on the pre-overlay optimizer |
| Annualized volatility limit | 0.25 |
Ex-ante portfolio-volatility constraint |
| Active-position cap | 0.50 absolute weight |
Applies to each k * (w_star_i - u_i); violations skip the target |
| Daily turnover limit | 1.0 |
sum(abs(target_weight_i - pretrade_weight_i)); violations skip the rebalance |
| Rebalance frequency | Daily | Signal and rebalance time are close |
| Platform execution | daily bars, MOC (market-on-close) | Auction fill at the official print |
| Commissions | $0.0040 per share, minimum $1.00 per order, capped at 1.00% of trade value | Charged per fill by the results module; all metrics are net of them |
| Slippage | 0 bps — not applied | Not an omission — MOC (market-on-close) fills at the auction print the backtest uses |
| Costs not modelled | short borrow fees / rebate, margin financing on leverage, market impact, exchange/regulatory/clearing pass-through fees, taxes | Excluded deliberately, not unknown |
| Backtest window | 2020-01-01..2024-07-01 |
Daily bars; no walk-forward analysis configured |
| Minimum order notional | $0.0 |
No platform minimum-notional restriction |
| # | Concern | Status |
|---|---|---|
| 1 | Rolling estimates use future observations | ✓ Estimates use adjusted-close observations through signal date t only and require a trailing 252-session window. |
| 2 | Close signal executed at the same day's open | ✓ Not present. The platform uses market-on-close execution at the official closing-auction print. |
| 3 | Missing prices are imputed or carried into optimization | ✓ Required return observations must be complete; affected rebalances are skipped rather than imputed. |
| 4 | Transaction costs omitted from reported performance | ✓ commissions $0.0040/share (min $1.00/order); slippage 0 bps — not applied |
| 5 | Adjusted-price history embeds unavailable corporate-action information | △ The calculation uses adjusted histories; point-in-time adjustment handling should be confirmed with the data vendor. |
w_star cannot be independently reproduced from the specification alone and cannot be identified with the paper's unconstrained growth-optimal portfolio.5/252 and 10/252 years when combined with annualized drift and covariance. Using T = 5 or 10 would overstate the drift horizon by 252 times and the diffusion horizon by approximately 15.87 times, so Equation 15 comparisons are not operationally identified.1.0, 2.0, and 4.0 plus a 0.25 annualized volatility cap, the audited executable constraint block lacks complete formulas and scenario-selection mechanics. Results therefore do not establish a reproducible risk-target-by-leverage comparison grid.w_star = V^-1 b; this invalidates the paper's exact maximal-growth, maximal generalized Sharpe, reference-invariance, drift-variance balance, and fixed-R optimality claims for the traded portfolio.R = k/(2-k). The paper's Table 1 calibration using a US bank account is not directly comparable to this SPY/GLD implementation.R, leverage scenario, relative-wealth barrier, or 5/10-day horizon. This run therefore cannot test the paper's analytical Kelly-line risk identities, barrier distributions, or target-specific positive-drift predictions as a group.Over the stated backtest, the strategy returned 59.24% net of charged commissions, with a 0.67 Sharpe ratio, 0.80 Sortino ratio, and 19.85% volatility. The 35.92% maximum drawdown and 0.30 Calmar ratio indicate that drawdown control was limited in realized portfolio terms despite the fractional-Kelly targets. The run recorded 1,872 trades, a 70.34% win rate, and a 2.50 profit factor; however, the aggregate output does not separate the individual risk-target and leverage scenarios needed to assess the benchmark-relative theoretical claims.
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,131 | 1.00x the 1,134 trading days in 2020-01-01..2024-07-01 |
| Distinct dates | 1,131 | one row per date |
| Date span | 2020-01-02 .. 2024-07-01 | |
| Sum of daily returns | 59.24% | matches the reported total return |
| Sharpe from these rows | 0.67 | stored 0.67 |
| Volatility from these rows | 19.85% | stored 19.85% |
| Max drawdown from these rows | -35.92% | stored -35.92% |
| Lowest the book stood | -27.50% | low-water mark, in units of starting capital |
| CAGR from these rows | 10.92% | stored 10.92% |
| Metric | Value |
|---|---|
| Total Return | 59.24% |
| Sharpe | 0.67 |
| Sortino | 0.80 |
| Calmar | 0.30 |
| Max Drawdown | -35.92% |
| Volatility | 19.85% |
| Beta vs SPY | 0.83 |
| Win Rate | 70.34% |
| Profit Factor | 2.50 |
| Total Trades | 1872 |
| Symbols | 2 (GLD, SPY) |