Buys deep RSI(5) oversold dips inside a 200-day SPY uptrend and exits when RSI reverts above 50 — a short-term mean-reversion setup.
Real internal-backtest statistics from the registry — Internal backtest · SPY daily bars (Yahoo Finance) · 89 trades · 1993–2026.
CAGR and exposure are not published for the library yet — we show “—” rather than invent them. Max drawdown, best year and worst year are undefined for the pooled Momentum universe backtest. Win rate is a share of trades, average return is per trade, and holding period is in trading days.
No fixed-window historical pattern is published for this strategy — its holding period is variable (or, for a market-wide read, there is no single held window), so a single averaged return path would misrepresent it. Use the backtest for its full trade-by-trade history instead. We never fabricate a curve.
Triple RSI buys short-term panic in an otherwise healthy market. It watches a fast 5-period RSI and only acts when four conditions line up at once — three RSI conditions plus a trend filter — then exits when RSI mean-reverts. It runs on SPY as a market-timing signal (/api/strategies) and, via the scanner, on individual stocks (/api/scan).
Short-term overreaction (mean reversion) inside a primary uptrend — the tendency of healthy markets to snap back after a fast, shallow pullback.
| Driver | Mechanism |
|---|---|
| Pullbacks in uptrends snap back | In a market above its rising 200-day MA, brief selloffs are usually profit-taking/liquidity events, not regime changes — buyers step back in. |
| Stacked confirmation | Requiring RSI oversold and still-falling and coming from a non-overbought state filters out both blow-off tops and names already turning, targeting genuine capitulation. |
| Trend filter | The 200-day gate keeps the strategy from "buying dips" in bear markets, where the edge inverts. |
The edge is a tendency, not a guarantee; mean reversion fails hard in trending bear markets, which is why the exit and the trend filter matter.
One pure core (tripleRsiSignalFromBars) backs the live SPY state, the scanner, and the backtest adapter, so the maths lives in exactly one place. Parameters (TRIPLE_RSI_PARAMS): RSI period 5, SMA period 200.
RSI(5) crosses above 50 — the mean reversion is complete.
stopLoss, firstTarget, riskPercent, and rewardRiskRatio are reported as null (never invented). entryPrice is the signal-bar close.The identical per-symbol logic runs across a universe via GET /api/scan?strategy=triple_rsi, returning each match's signal, a 0–100 confidence score, the passed-rule checklist, and metrics (rsi5, sma200, close).
Deterministic, from the shared buildConfidence framework. confidenceScore is a setup-quality measure (0–100), not a probability of profit. Components (maxima sum to 100):
| Component | Max | Awarded when |
|---|---|---|
trendFilter | 20 | close is above the 200-day SMA |
oversold | 15 | RSI(5) < 30 |
momentumDecline | 20 | RSI(5) fell 3 sessions in a row |
pullbackContext | 15 | RSI(5) was < 60 three sessions ago |
oversoldDepth | 30 | scaled by how far RSI(5) has pushed below 30 (deeper → higher) |
A bare BUY (all four gates met, RSI just under 30) scores ≈ 70 (Good); the more deeply oversold, the closer to 100 (Exceptional). On /api/strategies the live SPY score is null when no setup is active; on each /api/scan match it is always populated. Bands: <70 Weak · 70–79 Good · 80–89 Strong · 90–100 Exceptional.
The API returns the labels of the rules that currently pass; a full BUY shows all four:
| Dimension | Ideal |
|---|---|
| Market | Broad index or large-cap equities trading above a rising 200-day MA; constructive tape with periodic shallow pullbacks. |
| Trader | Active, rules-driven swing trader comfortable buying fear in an uptrend and holding through short-term volatility. |
| Timeframe | Daily bars; a few-day swing hold. |
| Avoid when | The asset is below its 200-day MA (bear market / downtrend); around binary events; or when costs would swamp the ~1.3% edge. |
historical.* is baked as of 2026; the live /api/backtest always recomputes from current data.historicalPattern.** Deliberate — the holding window is variable, so a fixed-offset average would misrepresent the strategy.Real responses from the live endpoints for this strategy.
GET /api/strategies?id=triple_rsi{
"strategies": [
{
"id": "triple_rsi",
"name": "Triple RSI Strategy",
"category": "Technical",
"asset": "SPY",
"description": "WHAT IT IS: The Triple RSI strategy is a technical, mean-reversion setup…",
"historical": {
"yearsTested": 34,
"winRate": 0.8989,
"averageReturn": 1.31,
"bestYear": 17.63,
"worstYear": -2.36,
"maxDrawdown": 7.37,
"averageHoldingPeriod": 5,
"profitFactor": 6.21,
"totalTrades": 89,
"source": "Internal backtest · SPY daily bars (Yahoo Finance) · 89 trades · 1993–2026"
},
"historicalPattern": null,
"status": "Upcoming",
"entryDate": "",
"exitDate": "",
"daysUntilEntry": 0,
"entryPrice": 583.12,
"stopLoss": null,
"firstTarget": null,
"riskPercent": null,
"rewardRiskRatio": null,
"confidenceScore": 12,
"confidenceBreakdown": { "trendFilter": 20, "oversold": 0, "momentumDecline": 0, "pullbackContext": 0, "oversoldDepth": 0 },
"explanation": "SPY does not currently trigger Triple RSI — 1 of 4 entry conditions in place. A signal fires only when all four align.",
"checklist": ["Above 200-day MA"],
"score": 55,
"recommended": false,
"weight": "medium"
}
]
}GET /api/scan?strategy=triple_rsi{
"strategy": "triple_rsi",
"supported": true,
"scanned": 500,
"matches": [
{
"symbol": "XYZ",
"signal": "BUY",
"score": 88,
"reasons": { "rsiBelow30": true, "threeDayDecline": true, "priorRsiBelow60": true, "above200MA": true },
"metrics": { "rsi5": 21.4, "sma200": 142.10, "close": 151.30 },
"entryPrice": 151.30,
"stopLoss": null,
"firstTarget": null,
"riskPercent": null,
"rewardRiskRatio": null,
"confidenceScore": 88,
"confidenceBreakdown": { "trendFilter": 20, "oversold": 15, "momentumDecline": 20, "pullbackContext": 15, "oversoldDepth": 18 },
"explanation": "XYZ rates 88/100 — a strong setup by the Triple RSI rules (a measure of setup quality, not a probability of profit)…",
"checklist": ["RSI(5) below 30", "3-day RSI decline", "RSI was below 60 three days ago", "Above 200-day MA"]
}
],
"skipped": []
}GET /api/backtest?strategy=triple_rsi{
"strategy": "triple_rsi",
"symbol": "SPY",
"range": { "requestedFrom": null, "requestedTo": null, "testedFrom": "1993-01-29", "testedTo": "2026-08-04", "barsTested": 8435 },
"metrics": {
"totalTrades": 89,
"winningTrades": 80,
"losingTrades": 9,
"winRate": 0.8989,
"averageReturn": 0.0131,
"medianReturn": 0.0132,
"bestTrade": 0.0781,
"worstTrade": -0.0737,
"averageHoldingPeriod": 4.83,
"profitFactor": 6.2147,
"totalReturn": 2.1381,
"maxDrawdown": 0.0737
},
"sampleTrades": [
{ "entryDate": "2026-03-12", "exitDate": "2026-03-31", "entryPrice": 566.10, "exitPrice": 552.74, "return": -0.0236, "holdingDays": 13 }
],
"openTradeEntryDate": null
}lib/market-data/prices.ts).*Past behaviour does not ensure future results. confidenceScore measures setup quality, not the probability of profit.*