📈 SPY Mean Reversion

Enhanced Multi-Signal Mean Reversion on SPY — Alpaca Paper Account · Extended Hours


● Paper Trading  |  📈 Long / Mean Reversion  |  🕐 Extended Hours

📡 Strategy Overview

A mean reversion equity strategy that buys SPY when multiple indicators signal an oversold extreme and exits when price reverts toward its mean. The script runs a continuous polling loop every 60 seconds during the extended session (4:00 AM – 8:00 PM ET) and uses the Alpaca market calendar to automatically skip weekends and holidays.

The strategy requires a core RSI oversold signal plus at least one confirming signal (MACD momentum turning, Bollinger Band touch, or adequate volume) before entering — reducing false entries compared to a pure RSI strategy. Maximum shares held at any time: 10.

Entry Logic — BUY (when flat)

ConditionRequired?Description
RSI(14) < 30RequiredCore oversold signal
MACD histogram rising≥ 1 of theseMomentum turning up
Price ≤ lower Bollinger Band≥ 1 of thesePrice stretched below mean
Volume ≥ 0.8× 20-bar avg≥ 1 of theseReasonable participation

Exit Logic — SELL (when long, ANY of)

ConditionDescription
RSI(14) > 70Overbought — primary exit
Price ≥ upper Bollinger BandMean-reversion profit target
MACD histogram falling + RSI > 55Momentum fading — early exit
Price drops 0.3% below entryStop-loss — capital protection

📊 Backtest Results (30-day, 1-min bars)

MetricOriginal (RSI only)Enhanced (Multi-signal)
Total return+1.07%+3.67%
Sharpe ratio1.266.31
Max drawdown−2.38%−0.88%
Win rate75.0%69.0%
Avg loser−$675−$245
Profit factor1.161.83
📋

Multi-Signal Advantage

The enhanced multi-signal version improved Sharpe ratio from 1.26 to 6.31 and cut average losses by 64% (−$675 → −$245) while reducing max drawdown by more than half.

⚙️ Parameters

Ticker
SPY
Max Shares
10
Position Size
95%
Stop-Loss
0.3%
ParameterDefaultDescription
SYMBOLSPYTicker to trade
RSI_PERIOD14RSI look-back period
RSI_OVERSOLD30Buy threshold
RSI_OVERBOUGHT70Sell threshold
MACD_FAST/SLOW/SIGNAL12/26/9MACD parameters
BB_PERIOD / BB_STD20 / 2.0Bollinger Band settings
VOLUME_MULTIPLIER0.8Minimum volume vs 20-bar avg
STOP_LOSS_PCT0.003Stop-loss threshold (0.3%)
POSITION_SIZE_PCT0.95Fraction of cash to deploy
MAX_SHARES10Maximum total shares held at once
INTERVAL_SECONDS60Polling frequency during session

🕐 Schedule

EventTime (ET)Days
Session start4:00 AMMon–Fri
Session end8:00 PMMon–Fri
Poll intervalEvery 60 sDuring session

Extended hours trading. The Alpaca market calendar is used to skip weekends and holidays automatically. When the market is closed the script sleeps in 5-minute chunks.

📅

Extended Hours

All orders use extended_hours=True and time_in_force=DAY. Unfilled limit orders are cancelled at the start of the next pass.

🧮 Technical Indicators

RSI (Relative Strength Index)

Period: 14. Computed using exponential weighted moving averages of gains and losses.

rsi = 100 − (100 / (1 + avg_gain / avg_loss))    # EWM, period=14

MACD

Fast: 12, Slow: 26, Signal: 9. The histogram (macd_line − signal_line) is compared bar-to-bar to detect momentum turning points.

macd_line   = EMA(close, 12) − EMA(close, 26)
signal_line = EMA(macd_line, 9)
histogram   = macd_line − signal_line

Bollinger Bands

Period: 20, Std dev: 2.0. Entry when price ≤ lower band; exit when price ≥ upper band.

middle = SMA(close, 20)
upper  = middle + 2.0 × std(close, 20)
lower  = middle − 2.0 × std(close, 20)

Volume MA

20-bar simple moving average of volume. Entry requires current volume ≥ 0.8× this average.

⚠️ Risk Assessment

Stop-Loss

0.3%

Max Position Size

95% of cash

Max Shares

10

Overnight Risk

Extended hrs

Order Type

Market

Direction

Long only
⚠️

Extended Hours Risk

The strategy trades during pre-market and after-hours sessions where spreads are wider and liquidity is lower than during regular market hours. This can lead to worse fills than indicated by backtest results.

📋

Position Sizing

Each entry deploys up to 95% of available cash, capped at MAX_SHARES=10. Subsequent entries add to the position up to the cap using a weighted average entry price.

🛠️ Prerequisites & Usage

Create & Activate Virtual Environment

python3 -m venv .venv
source .venv/bin/activate

Install Dependencies

pip install -r requirements.txt

Environment File — .env

Place in the same directory as the script. Credentials are loaded from Supabase at startup (account Aiv001).

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-service-role-key

Run Live Trading

python mean_reversion_spy.py

Run Backtest (Enhanced)

python backtest_enhanced.py

All output is logged to both stdout and logs/mean_reversion.log. Trades are logged with timestamp, entry/exit price, signals fired, and P&L.

⚠️

Paper Trading Only — Not Financial Advice

This strategy runs on an Alpaca paper trading account. Set USE_PAPER = False at your own risk. Past performance does not guarantee future results.

⚠️ Equities Permission Requirements (Alpaca)

This strategy trades SPY multiple times a day and will trigger the Pattern Day Trader (PDT) flag, which requires you to maintain a balance of $25,000 in your account.

A pattern day trader is defined by FINRA as any trader who executes four or more day trades within five business days in a margin account, where those trades represent more than 6% of their total trading activity during that period. Once flagged, your account must maintain a minimum equity of $25,000 on any day you trade; failure to do so will restrict the account to closing transactions only.

💰

$25,000 Minimum Balance Required

Ensure your Alpaca paper account reflects at least $25,000 equity before running this strategy to avoid PDT restrictions during testing.