Option quotes from after the close. This scan read its option chains once the options
market had shut, when market makers widen or pull their quotes. Liquidity was judged on open
interest alone, and every option price on this page is indicative — check a live quote during
market hours (09:30–16:00 New York) before placing anything.
Loading the latest scan…
The scanner finds names whose volatility has compressed — coiled springs that tend to
release with an outsized move. The options layer then reads what the market charges for
that move, and that is what decides which side of the trade you want to be on:
The bull and bear vertical spreads on each name's near expiry — the same one the
Scanner trades on. Each is a bet the stock goes one way: bull spreads pay if it rises,
bear spreads if it falls. A debit spread (bull call, bear put) is paid for up front; a
credit spread (bull put, bear call) is paid to you and pays out if the stock does not
move against it. The pick is the Scanner's own recommendation when that is one of
these; everything else is listed for comparison with no size, because a vertical is only
worth placing on a direction read the backtest has shown to work.
Every ≈13-month spread the chains support — the same names, held for a year instead of
a fortnight. Out here time decay barely works for you and the level of implied
volatility does most of the moving, so none of these are income trades: they are directional
positions with a defined cost. Click any row for the full legs, the management rules and the
caveats for that name.
Long-dated options are listed on January cycles, so the expiry nearest 13 months out can sit
anywhere from ~9 to ~18 months away. The real days-to-expiry is in every row.
Price a vertical spread from your broker's live quotes. Paste one expiry's chain — calls or puts —
and pick two strikes: you get a ladder of limit prices from mid to natural, a model fair
value that says how far down the ladder is still worth going, the probabilities and expected
value at every rung, and every strike pair in the chain ranked. Nothing is sent anywhere;
what you type is kept in this browser only.
Options
How it works
Ladder. Mid is halfway between bid and ask on each leg — the price a screen shows and nobody
is promised. Natural is selling every bid and buying every ask — the price you can always get. The
planned fill, a third of the way from mid to natural, is what the scanner assumes everywhere else.
Fair value. Both legs priced by Black-Scholes at one volatility: yours if you enter it,
otherwise the chain's at-the-money IV. Where the chain gives no IV, it is solved from each strike's
mid. A strike whose price no volatility can produce is shown and left out.
Expected value is fair value against the price you trade at, per spread. It is zero at fair
value by construction, so it measures how much a given limit gives away (or gains) against the model —
never more trustworthy than the volatility you feed it. Probabilities are at expiry, lognormal, same
volatility; early exits and assignment are not modelled.
The ranked table behind the cards. Score is how coiled the chart is; Premium is
how rich the options are. High score with a low premium score is the cleanest buy-premium
setup; high score with a high premium score is the cleanest sell-premium setup. Click any
header to sort.
Closing price for every screened name over the recent window — shorter than the history
behind the Seasonality view, because a range and a high/low are a read on where a name sits
now. Faint vertical lines mark each calendar-year boundary, so you can read the move
year to year. The badge is the trailing twelve-month change.
Loading price history…
The same history cut by calendar month instead of by date: every whole month in the
window becomes one return, and those returns are grouped into twelve buckets. It answers
when in the year these names have tended to rise and fall — useful for timing an entry
you were going to make anyway, or for knowing which month you are fighting.
Loading the month tables…
One trade, placed in the same week every year. Set the week you would buy, how long
you would hold it and how far the name has to move — this counts the years that
closed past that move against the years that did not, over the same weekly
history behind the Charts tab. The verdict is the exit: eight weeks at +1% asks
whether the name is 1% up at the close of week eight, not whether it got there and gave
it back. Whether it was ever touched is reported beside it, never as it.
The target can be zero or negative. An in-the-money vertical is already past
its breakeven at today's price, so its real question is did it hold up rather than
did it travel — set −3% and this counts the years that closed no worse than 3%
down.
A target is a distance, not a level: $250 meant something very different in 2016,
so you set a percentage and each year's target price is worked out from that year's own
entry. Every one of them is in the table.
Direction
Buy week — 37
Loading the weekly history…
The debit is yours, not the market's. This repo holds ten years of stock bars
and no option history, so nothing here can look up what this really cost in
October 2018 — you set it below and it is held constant across every year. In life
it is not: the debit climbs with implied volatility, and implied volatility climbs
when the market is frightened, so the years you most want the trade are the years it
cost most. Everything after that one number is exact — an option held to expiry is
worth its intrinsic value and that comes from the closes already on this page. The
breakeven debit in the totals is the number to take to a live quote.
Structure
A rule, run over every name and every week of the same history the Repeat test
walks. Pick what would have made you buy — a squeeze, a new high, a close under the
average — say how long you would hold it and how far it has to move, and this finds
every time that rule ever fired and counts what the next weeks did.
The rule is decided on the week's own close and the weeks before it, never on
anything after, and the trade is entered at that close. The verdict is the exit,
as on the Repeat test: where the trade closed, not the best price it saw on the way.
The rate on its own means nothing — these names rose over this decade, so
almost any rule looks good. What this leads with is the edge: the same names,
hold and target entered on every week, subtracted from the rule's own record.
A rule that beats that gap picked the weeks; a rule that does not was just holding the
market.
Direction
Off, one position at a time — what you
could actually have held.
Loading the weekly history…
Searching…
The debit is yours, not the market's. This repo holds ten years of stock
bars and no option history, so nothing here can look up what one of these
really cost on the week it opened — you set it below and it is held constant
across every trade. In life it is not: the debit climbs with implied volatility,
and implied volatility climbs when the market is frightened. That bites harder
here than on the Repeat test, because a rule like the squeeze selects for
a volatility regime, so its trades are not a random sample of what options cost.
Everything after that one number is exact. The breakeven debit in the
totals is the number to take to a live quote.
Structure
Does the Setup Score work?
Loading backtest…
How the weights were set
Loading calibration…
Loading the regime backtest…
Every definition below ships inside data/scan.json alongside the numbers it
describes, so an explanation here can never drift from the field it explains.
What the numbers mean
The strategies
How the pipeline works
Backend — data only
Each weekday after the US close a GitHub Action fetches the ETF holdings that define
the universe, re-screens them on industry plus debt and cash ratios, downloads daily prices,
recomputes the indicators without look-ahead, reads the option chains for the top-ranked
names — the front month and a ≈13-month expiry — runs both strategy engines, and writes
JSON:
data/scan.json — signals, IV read, recommendations, and this copy
data/charts.json — downsampled price history, and the same closes grouped by calendar month
data/weekly.json — the same history as one row per ISO week, which the Repeat test walks
data/backtest.json · data/calibration.json
data/regime.json — the Market regime tab, rewritten weekly by its own workflow
data/signals.csv — the flat table, for spreadsheets
Python renders no HTML at all. Deciding what to trade got complicated enough that it
needed to be data, not markup.
Frontend — this page
Hand-written, checked into public/, no build step and no external assets.
It fetches the JSON above and renders it. Nothing regenerates it, so you can restyle the
dashboard without touching the scanner — and read the same data from anything else that
speaks JSON.
Run it locally with python run.py then
python -m http.server --directory public 8765. Opening the file over
file:// will not work: the browser blocks fetch there.