LEAPS Opportunity Finder — Methodology
This page documents exactly how the LEAPS Opportunity Finder scores contracts, weights each factor, filters for eligibility, incorporates the market regime, sizes positions, and validates itself via the paper trader. Nothing is hidden. Every weight is documented and every version bump is logged.
scoring_version tag; nightly grading marks positions to market and buckets closed trades into deciles so we can measure whether higher scores actually predicted higher realized P&L. That validation loop is public at /leaps/paper/ — no data is hidden.
Contents
- 1. What LEAPS are (and why they need their own scanner)
- 2. Universe & contract eligibility
- 3. The four sub-scores
- 4. Composite weights (call vs put)
- 5. Regime layer
- 6. Position sizing
- 7. Scenario grid (spot × time)
- 8. Walk-forward validation via paper trader
- 9. Watchlist & alerts (local-only)
- 10. Data sources & refresh cadence
- 11. Known limitations & caveats
- 12. Scoring-version history
1. What LEAPS are (and why they need their own scanner)
A LEAPS option (Long-term Equity AnticiPation Security) is a listed equity option with an expiration date more than one year out. Because they're deep-time contracts, the trade thesis is fundamentally different from short-dated options: theta bleed is slow, gamma is modest, delta is the dominant Greek, and the outcome is driven far more by the underlying's directional path over months than by short-term implied-volatility mean reversion.
Standard option screeners (like our Custom Screener) optimize for premium collection or spread structure. They rarely surface LEAPS because those contracts fail the usual short-DTE liquidity, delta, and yield filters. The LEAPS Opportunity Finder is purpose-built for the opposite problem: find the underlyings whose 6–24 month technical + fundamental setup best justifies a directional bet, and pick the contract on that name that gives you the cleanest leverage with acceptable liquidity.
2. Universe & contract eligibility
2.1 Universe
The scanner supports six universes and custom ticker lists:
- NDX-100 — Nasdaq-100 constituents (~100 names).
- SP500 top-200 — largest 200 S&P 500 names by index weight.
- DJIA — the 30 Dow Jones Industrial Average components.
- High-volume optionable — hand-curated ~80 names with high options volume + tight LEAPS spreads.
- Sector focus — subset filtered to a specific GICS Level-1 sector.
- Custom — user-supplied comma-separated ticker list (up to 50 symbols).
2.2 Contract eligibility filter
For each ticker, we pull the full options chain and keep only contracts that pass:
- DTE ≥ 300 days by default (LEAPS threshold; slider min 180, max 730).
- Open interest ≥ 100 by default (slider min 25, max 1000).
- Bid–ask spread ≤ 15% of mid, but only when both bid and ask are live. On weekends and after hours, when the market is closed and bid/ask both = 0, this filter is bypassed and mid falls back to the last trade.
- Delta window — calls: 0.55–0.85 (moderate ITM); puts: −0.85 to −0.55. This targets the "leverage sweet spot" where delta is high enough to move meaningfully with the underlying but not so ITM that you're paying pure intrinsic value.
- Mid price > $0 (screens out contracts with no market at all).
3. The four sub-scores
Every eligible contract gets four sub-scores on a 0–100 scale. All formulas are deterministic and version-locked.
3.1 Technical score (weight varies by side)
Measures the underlying's directional setup. Components:
- Trend regime (SMA 50 vs 200 crossover state, price above/below both).
- Momentum — 60-day return z-score, Wilder-smoothed RSI (14), MACD histogram sign.
- Relative strength vs benchmark (SPY for equities, sector ETF for sector members) — 60-day rolling excess return, tanh-compressed to [0,100].
- Volatility structure — ATR/price ratio (want directional but not chaotic).
- Support/resistance context — proximity to 52-week high (calls) or low (puts), swing-pivot cushion.
Directionality flips for puts: bearish trend, negative momentum, weak relative strength, proximity to 52-week low all score higher for puts.
3.2 Contract quality score
Measures how well the specific contract expresses the thesis. Components:
- Leverage ratio — |delta| × (spot / mid). LEAPS with 3–7× leverage score best; below 2× isn't worth the option premium, above 10× is usually too far OTM.
- Break-even distance — how much the underlying must move (in %) to hit break-even at expiration. Tighter is better (higher score).
- Time premium % — extrinsic value / mid. Too low = essentially just stock at higher fees; too high = paying too much for time.
- Theta drag — annualized theta as % of mid. Lower is better.
- Liquidity — open interest score + spread score (spread bypassed on weekends).
3.3 Fundamental score
Lightweight fundamentals from Polygon reference data + basic screens. Not a substitute for a full fundamental model — this is a sanity check.
- Market cap band — mid/large caps score higher (LEAPS on illiquid small-caps are risky).
- Sector membership — sector tilt applied via regime layer.
- Earnings recency — recent surprise history (if available in data feed).
Honest caveat. Fundamentals get only 10% of the composite because our data feed doesn't give us cash-flow statements, guidance, or analyst estimates. Users who want a fundamentals-first LEAPS screen should combine this tool with an outside fundamental filter.
3.4 Risk score
Penalizes contracts likely to blow up.
- IV percentile — buying LEAPS in the top decile of realized IV is expensive; penalty applied.
- Earnings-window proximity — a earnings-date event after expiration is neutral; one within the holding window is a risk factor if binary.
- Historical drawdown — max 6-month drawdown from Polygon aggs. High-vol names get a haircut.
- Regime alignment penalty — a call in a confirmed bear tape (or a put in a confirmed bull tape) gets a risk score penalty even if its technicals look attractive.
4. Composite weights (call vs put)
The overall score is a weighted linear combination of the four sub-scores, with different weights for calls vs puts:
| Sub-score | Call weight | Put weight |
|---|---|---|
| Technical | 30% | 35% |
| Contract quality | 35% | 30% |
| Fundamental | 10% | 5% |
| Risk | 25% | 30% |
| Total | 100% | 100% |
Why puts weight risk higher and fundamentals lower? A short-thesis LEAPS put is inherently more asymmetric: you're leaning into "this company/tape gets worse from here." Bad fundamentals are what you want for a put thesis, so scoring them positively muddies the signal — better to trust the technical breakdown + volatility context. Risk weight goes up because put losses can be sudden (short squeezes, buyouts, forced covering).
Weights are hand-set, not fit. These weights come from Van-Tharp-style expert priors, not backtest fitting. That means they'll be wrong. The paper-trader validation loop (§8) exists specifically to measure how wrong, on which sub-scores, and to guide the next re-weight.
5. Regime layer
Every scan runs the market regime calculator first. Inputs:
- SPY, QQQ, IWM — trend state (above/below SMA 200), 20-day return z-score, breadth via ADX.
- VIX — level and slope; used to classify vol regime (compressed / normal / stressed).
Output: a bull score from 0–100 plus a categorical state (bull, neutral, bear) and vol state (low, normal, high).
Alignment for each candidate
- Call in bull regime → aligned (chip: green "aligned").
- Put in bear regime → aligned.
- Call in bear regime → counter (chip: red "counter") — risk score gets a penalty; not disqualified.
- Put in bull regime → counter — same treatment.
- Anything in neutral regime → neutral (no adjustment).
The regime chip is displayed on every scanner row so you can see at a glance whether a candidate is fighting the tape.
6. Position sizing
The candidate detail page includes a position-sizing calculator with three inputs:
- Account equity — how much total capital you're deciding across.
- Max risk per trade — what % you're willing to lose on this one position if the option expires worthless (default 2%; slider 0.5–20%).
- Contract mid — auto-filled.
Output: recommended number of contracts to buy, with warnings if the position would exceed liquidity constraints (more than 5% of open interest) or if the total capital deployed would exceed 20% of equity even at 2% risk (in which case the position is too concentrated).
7. Scenario grid (spot × time)
Every candidate detail page renders a 9-spot × 5-time-step BSM scenario matrix:
- Spot axis — nine states from −25% to +25% of current spot in 6.25% increments.
- Time axis — today, 30d, 90d, 180d, and at-expiration.
- Value in each cell — full BSM contract value at that spot & time, computed client-side with Abramowitz-Stegun 7.1.26 normal-CDF approximation.
Three sliders let you shock the scenario:
- IV shift (−30 to +30 vol points) — models a volatility-crush or expansion event.
- Rate shift (−200 to +200 bps) — for rate-sensitive names.
- Dividend yield shift — Merton-style continuous-dividend adjustment.
Under each scenario, the P&L is color-coded (green = profit, red = loss) so you can eyeball breakeven and drawdown paths.
8. Walk-forward validation via paper trader
The scanner ranks contracts. But the honest question is: do higher-ranked contracts actually deliver better realized P&L?
8.1 How trades get opened
Every time a user clicks the Paper button on a scanner row (or from a detail page), the full contract + all four sub-scores + the regime state + the current scoring_version tag are persisted to a Cloudflare KV namespace. Users don't opt-in to sharing data — the paper trades are anonymous by design (only the position itself, not who opened it).
8.2 Nightly grading
A Workers cron job runs each night:
- Iterate every open paper trade.
- Fetch the current option mid price from Polygon.
- Compute mark-to-market P&L per contract and % change from entry.
- Close trades that are past expiration or that have been open ≥ 365 days.
- Assign a grade: big-win (>+50%), win (+10 to +50%), flat (−10 to +10%), loss (−10 to −50%), big-loss (<−50%).
8.3 Score-decile analysis
On /leaps/paper/, closed paper trades are bucketed into deciles by their overall opportunity score at entry. The page shows:
- A bar chart of average P&L per decile — a monotone-increasing shape (left low → right high) means the score has real predictive power.
- The Spearman rank IC (rank correlation) between decile average score and decile average P&L. IC ≥ 0.30 is strong; 0.10–0.30 is meaningful; below 0.10 is noise.
- Linear R² for consistency.
- Hit rate, average P&L, median P&L across all closed trades.
8.4 The re-weighting loop
Once enough trades have graded out (target: 30+ per decile, so ~300 closed trades total for a scoring version), we can:
- Regress realized P&L on each sub-score to identify which factors carry signal and which are noise.
- Re-weight the composite (e.g., if technical shows IC 0.35 and fundamental shows IC 0.02, shift weight from fundamental to technical).
- Bump the
scoring_versiontag. The next generation of paper trades will be graded against the new weights.
This is walk-forward validation, not in-sample fitting. Each version's trades are graded only against outcomes that came after the version was published. No look-ahead bias.
Fair warning. With fewer than ~50 settled trades total, decile buckets are dominated by noise. The chart won't stabilize until the paper trader has accumulated real volume — which requires users to actually click the Paper button on candidates they find promising. Until then, treat the composite score as an educated prior, not a validated signal.
9. Watchlist & alerts (local-only)
The Watchlist page lets users pin tickers and specific contracts, plus set rule-based alerts. All state lives in browser localStorage: no login, no server-side user data, no cross-device sync (users can export/import JSON to move between machines).
Three alert rule types:
- Score threshold — fire when a watched ticker's best call or put LEAPS candidate scores above a user-set threshold.
- Price cross — fire when a ticker's spot price crosses above or below a level.
- Regime change — fire when the market regime flips into a specific state (or any change).
Alerts are evaluated on page load and any time the user clicks "Check now." Rules have a 4-hour rate limit per rule to prevent duplicate firings.
10. Data sources & refresh cadence
- Options chain, quotes, contracts — Polygon.io Options Starter tier. Quotes are ~15 minute delayed during market hours.
- Underlying prices & historical aggs — Polygon.io Stocks tier (1-year of daily bars for indicator calculation).
- Reference data (sector, market cap, splits, dividends) — Polygon.io reference.
- VIX + regime inputs (SPY/QQQ/IWM) — Polygon.io daily bars.
The Worker caches scan results in Cloudflare edge cache for 30 seconds, which is why hitting refresh doesn't burn API quota. Individual candidate detail pages fetch fresh option data on each visit.
Data license status. As of this writing, the site runs on Polygon's Individual Use tier. Any commercial or subscription-tier launch is blocked pending business-use licensing.
Current on-demand scan cap: 5 tickers. Polygon's per-minute rate limit on the current data plan makes it infeasible to scan the full 200–300 ticker universes within a single request. The scanner ranks the first 5 names of your chosen universe. A nightly warm-cache (Workers Cron) is the planned fix — it will pre-compute the full universe and store rankings in KV, so users get instant results across all names regardless of Polygon rate limit. Until then, use ?universe=custom&t=NVDA&t=AAPL&t=SPY to scan up to 5 tickers of your choosing.
11. Known limitations & caveats
- American-style options are treated as European for BSM pricing. This under-estimates value on deep-ITM contracts and slightly mis-estimates delta near early-exercise-optimal points (dividend-heavy names near ex-div).
- No live IV surface — we use per-contract IV from Polygon rather than fitting a full skew/term surface. Scenario shifts assume parallel IV moves.
- No borrow-cost adjustment for puts — the BSM engine assumes zero borrow cost, which under-values deep-OTM puts on hard-to-borrow names.
- Regime layer uses a single window (60d) — it can whipsaw around trend inflections.
- Fundamental weight is intentionally small — see §3.3 caveat. Users who care about earnings quality should overlay their own filter.
- Paper trader has no fill assumptions — trades open at last mid. Real fills would experience slippage, and deep-ITM LEAPS on illiquid names may not fill at all at posted mid.
- Not investment advice — this is a screening + validation tool. All trade decisions and risk-taking are yours.
12. Scoring-version history
Version log will be updated as the paper-trader validation loop produces enough data to justify re-weighting. Users can subscribe to the Research page for public write-ups of any material change.
Questions or corrections? The full source code for the scoring engine lives at github.com/VYZE-INC/optiontrading under worker/src/leaps-*.js. Weight files, universe lists, and grading logic are all visible and diffable. If you find a bug in the math, open an issue.