A Sharpe-single-index residual framework applied to the NASDAQ-100, with an MSCI-lineage Quality + Value composite as the deployed instantiation. Companion repository to the dissertation.
Headline (2021-04-01 to 2025-12-31, 20 quarterly rebalances, vs QQQ benchmark): NDX-QRV cumulative return +126.58% vs QQQ +99.62%, Sharpe 0.828 vs 0.649, CAPM alpha +4.52% per year, beta 0.875, maximum drawdown -25.77% vs -35.12%, tracking error 7.54%.
This is a research artifact, not a product. It implements a quality-tilted equity index on the NASDAQ-100, built point-in-time and survivorship-corrected by backward-replay reconstruction of index membership, with fundamentals and prices pulled from the Financial Modeling Prep /stable API. The signal is an MSCI-lineage Quality composite (return on invested capital, free-cash-flow yield, a balance-sheet safety score, minus an EV/EBITDA valuation penalty), each input z-scored within sector following Bender, Briand, Melas, and Subramanian (2013). The deployed index selects the top 30 names by composite score across the full universe (an absolute, cross-sector selection), which is the pure-quality limit (lambda equal to one) of a residual-alpha framework that generalizes to a Sharpe single-index residual overlay. The index is not sector-neutral by design: sector tilts surface as a feature of the quality ranking rather than being constrained away. Version 0.4.1 corrects a NAV-level aggregation bug that had removed roughly 250 to 350 basis points per year of return from the prior backtest engine.
Python 3.11 or newer. The unit-test suite runs offline and needs no API key; reproducing the live backtest needs a free FMP key in .env.
Reproduce the headline empirics end to end in a single process:
git clone https://github.com/leoromero-quant/smart-beta.git
cd smart-beta
uv sync # or: pip install -e .
cp .env.example .env # fill in FMP_API_KEY
uv run python -m smart_beta.examples.reproduce_v0_4_1The last command prints the canonical summary table and exits. It loads the committed v0.4.1 results by default and finishes in well under a minute; pass --full to re-run the five-year backtest against live FMP data.
The chart shows the cumulative total-return path of NDX-QRV against QQQ over the five-year window, both indexed to 1.0 at the first rebalance. The quality tilt compounds ahead of the cap-weighted benchmark while taking a shallower drawdown through the 2022 selloff.
| Metric | NDX-QRV | QQQ | Diff |
|---|---|---|---|
| Cumulative return | +126.58% | +99.62% | +26.96 pp |
| Annualized return | +18.93% | +15.78% | +3.15 pp |
| Annualized volatility | 20.95% | 22.57% | -1.62 pp |
| Sharpe ratio | 0.828 | 0.649 | +0.179 |
| Maximum drawdown | -25.77% | -35.12% | +9.35 pp |
| CAPM alpha (annualized) | +4.52% | 0.00% | +4.52 pp |
| Beta | 0.875 | 1.000 | -0.125 |
| Tracking error | 7.54% | n/a | n/a |
| Information ratio | 0.356 | n/a | n/a |
Risk-free rate is zero by convention; Sharpe and information ratio follow the Grinold-Kahn annualization. Numbers are the committed v0.4.1 results in data/exports/backtest_ndx_qrv_v0.4_summary.json.
The universe is the NASDAQ-100 reconstructed point-in-time at each quarter-end by backward replay of the index change log, so a name held at a past rebalance stays in that rebalance even if it later left the index. Of the 103 names in the 2021-Q1 universe, 36 had left the index by the end of 2025; all are retained in the windows where they were members, which removes survivorship bias. Fundamentals are lagged one quarter to respect the 10-Q filing delay, so no figure enters a rebalance before it was public. Prices are split- and dividend-adjusted through the FMP /stable/historical-price-eod/dividend-adjusted endpoint, giving a total-return basis.
The backtest holds each quarter's book statically until the next rebalance and chains returns at the NAV level: dollar positions ride prices and the portfolio value is the sum of those positions each day. The earlier engine aggregated a weighted average of per-name log returns, which by Jensen's inequality understates the true portfolio return by about half the cross-sectional return variance per day. On a thirty-name book that drag was roughly 5 percentage points per year. Version 0.4.1 replaces that with NAV-level chaining, the same measurement the benchmark already used. Information ratios use the Grinold-Kahn convention (annualized active return over annualized tracking error).
A longer treatment of the MSCI lineage is in docs/METHODOLOGY_LINEAGE.md.
smart_beta/ core library: universe, fundamentals, quality score, portfolio, backtest
examples/ one-command reproduction entrypoint
scripts/ export and diagnostic drivers
tests/ 121 offline unit tests
Latex/ the working paper, its figures, and the built PDF
docs/ methodology lineage, results report, rendered figures
data/exports/ committed v0.4.1 summary and aggregation-correction audit
notebooks/ quickstart notebook with rendered outputs
.github/ continuous integration workflow
uv run pytestThe suite is 121 offline unit tests covering the universe reconstruction, point-in-time fundamentals, quality scoring, portfolio construction, the cap-and-redistribute weighting, and both backtest aggregation paths. No network or API key is required.
If you use this code or the empirical results in academic work, please cite:
Suárez Romero, L. (2026). Smart Beta NASDAQ Quality ROIC-Value Index: A Factor Efficiency-Value Weighted Index. Working paper. https://github.com/leoromero-quant/smart-beta
Foundational reference: Bender, J., Briand, R., Melas, D., and Subramanian, R. A. (2013). Foundations of Factor Investing. MSCI Research Insight.
Leonardo Suárez Romero, leoromero.dev
Released under the MIT License. See LICENSE.
