annual
Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-09-26, from is-the-sp-500-sharia-compliant.
| year | spy_pct | spus_pct | hlal_pct | spus_minus_spy_pct |
|---|---|---|---|---|
| 2020 | 15.1 | 22.5 | 22.1 | 7.4 |
| 2021 | 28.8 | 36.2 | 28.9 | 7.4 |
| 2022 | -19.9 | -24 | -19.3 | -4 |
| 2023 | 24.8 | 34.2 | 30.6 | 9.4 |
| 2024 | 24 | 26.9 | 17.3 | 2.9 |
| 2025 | 16.6 | 19.1 | 18.5 | 2.5 |
| 2026 | 12.9 | 17.2 | 21.4 | 4.3 |
- Rows × columns
- 7 × 5
- Computed
- Completeness
- No missing values
- Source
- US exchange, SIP and OPRA market data
- Licence
- Strasmore terms · free, no signup
What each column holds
| Column | Type | Range | Notes |
|---|---|---|---|
year |
text | 7 distinct values (2020, 2021, 2022…) | |
spy_pct |
number | -19.9 to 28.8 | percent |
spus_pct |
number | -24 to 36.2 | percent |
hlal_pct |
number | -19.3 to 30.6 | percent |
spus_minus_spy_pct |
number | -4 to 9.4 | percent |
Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.
Run it yourself
This is the exact query behind the result above. Change a ticker, a date or a column and run it against the warehouse — no account, no key. The no-signup tier is smaller than the one this page was computed on; a query that reaches past it comes back saying which plan runs it.
WITH yearly AS
(
SELECT
toYear(date) AS y,
ticker,
argMin(toFloat64(close), date) AS first_close,
argMax(toFloat64(close), date) AS last_close
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('SPY', 'SPUS', 'HLAL')
AND date >= '2020-01-01'
GROUP BY y, ticker
)
SELECT
toString(y) AS year,
round(100 * (maxIf(last_close, ticker = 'SPY') / maxIf(first_close, ticker = 'SPY') - 1), 1) AS spy_pct,
round(100 * (maxIf(last_close, ticker = 'SPUS') / maxIf(first_close, ticker = 'SPUS') - 1), 1) AS spus_pct,
round(100 * (maxIf(last_close, ticker = 'HLAL') / maxIf(first_close, ticker = 'HLAL') - 1), 1) AS hlal_pct,
round(100 * (maxIf(last_close, ticker = 'SPUS') / maxIf(first_close, ticker = 'SPUS')
- maxIf(last_close, ticker = 'SPY') / maxIf(first_close, ticker = 'SPY')), 1) AS spus_minus_spy_pct
FROM yearly
GROUP BY y
ORDER BY y
Work with this data in your AI assistant
Opens ready to query, with this page's data. Free, no account.