One session, one formula, different amounts of warm-up
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-08-17, from Why Your RSI Differs Between Platforms.
| warmup_bars | rsi_wilder | rsi_simple |
|---|---|---|
| 0 | 49.07 | 49.07 |
| 1 | 42.35 | 49.07 |
| 2 | 39.73 | 49.07 |
| 5 | 38.03 | 49.07 |
| 10 | 43.08 | 49.07 |
| 20 | 46.95 | 49.07 |
| 40 | 47.14 | 49.07 |
| 80 | 46.92 | 49.07 |
| 160 | 46.91 | 49.07 |
| 250 | 46.91 | 49.07 |
- Rows × columns
- 10 × 3
- 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 |
|---|---|---|---|
warmup_bars |
text | 10 distinct values (0, 1, 10…) | |
rsi_wilder |
number | 38.03 to 49.07 | |
rsi_simple |
number | every row is 49.07 |
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
daily AS
(
SELECT arraySort(groupArray((day, px))) AS pts
FROM
(
SELECT
date AS day,
toFloat64(max(close)) AS px
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'AAPL'
AND date >= '2025-01-02'
AND date <= '2026-06-30'
GROUP BY day
)
),
steps AS
(
SELECT arrayPopFront(arrayDifference(arrayMap(p -> p.2, pts))) AS chg
FROM daily
),
grid AS
(
SELECT
arrayMap(x -> greatest(x, 0.0), chg) AS up,
arrayMap(x -> greatest(-x, 0.0), chg) AS dn,
toInt64(length(chg)) AS e,
toInt64(arrayJoin([0, 1, 2, 5, 10, 20, 40, 80, 160, 250])) AS warmup
FROM steps
),
seeded AS
(
SELECT
warmup,
(arraySum(arraySlice(up, e - warmup - 13, 14)) / 14) * pow(13.0 / 14.0, warmup)
+ arraySum(arrayMap((g, j) -> g * pow(13.0 / 14.0, toInt64(j) - 1),
arrayReverse(arraySlice(up, e - warmup + 1, warmup)),
arrayEnumerate(arraySlice(up, e - warmup + 1, warmup)))) / 14 AS up_wilder,
(arraySum(arraySlice(dn, e - warmup - 13, 14)) / 14) * pow(13.0 / 14.0, warmup)
+ arraySum(arrayMap((g, j) -> g * pow(13.0 / 14.0, toInt64(j) - 1),
arrayReverse(arraySlice(dn, e - warmup + 1, warmup)),
arrayEnumerate(arraySlice(dn, e - warmup + 1, warmup)))) / 14 AS dn_wilder,
arraySum(arraySlice(up, e - 13, 14)) / 14 AS up_simple,
arraySum(arraySlice(dn, e - 13, 14)) / 14 AS dn_simple
FROM grid
)
SELECT
toString(warmup) AS warmup_bars,
round(100 - 100 / (1 + up_wilder / greatest(dn_wilder, 0.000001)), 2) AS rsi_wilder,
round(100 - 100 / (1 + up_simple / greatest(dn_simple, 0.000001)), 2) AS rsi_simple
FROM seeded
ORDER BY warmup
Work with this data in your AI assistant
Opens ready to query, with this page's data. Free, no account.