EMA9 Morning Breakthrough
Strategy #1 — 3-Candle 9-EMA Morning Breakout (0DTE). Live parameter sheet.
ALPACA · PAPER
SPY · 0DTE OPTIONS
ENTRIES 9:30–11:30 ET
Core
| Underlying | SPY |
| Instrument | 0DTE options — calls and puts (single-leg, long) |
| Candle timeframe | 10-minute |
| Indicator | 9-period EMA on close — ewm(span=9, adjust=False) |
| Direction logic | Breakthrough stop-and-reverse (trend ride) |
| Account / sizing | Paper · 1 contract / entry (EMA9_CONTRACTS) |
Entry signal (exact)
Let i = the candle now forming; its open is the fill price.
c1=i-1, c2=i-2, c3=i-3 are the last three completed 10-min candles.
CALL → c3.close ≤ c3.ema9 (price was at/below the EMA)
AND c2.close > c2.ema9 (breakthrough close above)
AND c1.close > c1.ema9 (second close above)
AND open(i) > c1.ema9 (candle i opens above prior EMA)
PUT → the exact mirror below the 9-EMA
| Fill trigger | Open of candle i (open-trigger). Waiting for the close was tested and is worse — it enters ~10 min later at a worse price. |
| Entry window | 9:30 – 11:30 ET only. No new entries (or reversals into a new position) after 11:30. |
Strike selection
| Candidates | Most-OTM first: 2-OTM → 1-OTM → ATM (ATM = round(spot); ±1 strike steps) |
| Rule | Pick the most-OTM strike whose |delta| > 0.30. Fallback = ATM. |
| Delta source | Black–Scholes IV inversion on the live option mid (vendored from greeks.py); r = 0.043, T = time to 16:00 ET close |
| Order type | Marketable limit at the ask |
Position management & exits
| Stop-and-reverse | An opposite confirmed breakthrough exits the current side (allowed any time) and opens the other — but a new entry only happens inside 9:30–11:30 ET. |
| Stop-loss | None. Every stop level tested reduced total return (winners routinely dip before they run). |
| Profit target | None — ride to reverse or to the close. |
| End of day | Flat by 15:56 ET (0DTE force-close). |
Engine / runtime
| Poll interval | 15 s |
| Acts per candle | Once, at the new 10-min boundary |
| Stock data feed | IEX (1-min bars → 10-min) |
| Option data feed | indicative |
| Delta floor | 0.30 |
| Risk-free rate | 0.043 |
Files: ema9_live.py (session) + ema9_watchdog.py (restart + single-instance lock). Logs: logs/ema9_live.log, trades logs/ema9_live_trades.csv.
Validation context (backtest)
12-month run (2025-06 → 2026-06), open-window, open-trigger: 195 trades, win 27%,
NET total +5,297% (sum of per-trade %), $12k DCA → $118,788, worst drawdown 20%.
Out-of-sample 6-mo slice: OPEN window +2,115% vs all-day −1,676% — the time filter is what's robust.
High variance: ~25% win rate; profit leans on rare morning-trend days. This is the best lead found,
not validated income — which is why it runs on paper first.