# Methodology and data dictionary ## Scope and preselected rules - Dataset: **FlashAlpha Options Research Taster, 2020–2025, v1**. - Three fixed ETFs: SPY, QQQ, IWM. These are a convenience sample of liquid equity ETFs, not an unbiased universe. - January 2020 through December 2025: 72 months × 3 ETFs = 216 scheduled windows. - Use the first observed trading day's EOD chain to select contracts. Enter at the second observed trading day's EOD quote. Close at the twelfth observed trading day's EOD quote: ten trading-session intervals after entry. All three ETFs' scheduled dates were checked to agree. - The dates come from available underlying observations, not a separately licensed exchange calendar. No interpolation or extra dates are invented. - Front expiration: nearest 35 calendar days from signal, permitted range 30–45. Back expiration: nearest 65, range 55–80. Ties select the earlier expiration. - C50/P50, C25/P25 and C10/P10 mean nearest absolute archived delta 0.50, 0.25, 0.10 in the chosen expiration. Reject targets more than 0.10 away. Strike breaks ties deterministically. No parameter tuning. - CATM/PATM share the strike nearest signal-day underlying spot. Calendars use that exact strike across both expirations. Diagonals use front 25-delta and back 50-delta legs, with different strikes. - Iron butterflies use the shared ATM body and 10-delta wings; widths may differ. Condors use 25-delta shorts and 10-delta longs. These are specific variants, not every possible implementation of those names. - One contract per option leg, multiplier 100. Stock overlays hold 100 shares. All positions close before expiry. No stops, targets, rolls, leverage scaling, delta hedging or reinvestment. - The published rules are frozen in this release; no parameter search is part of the provided pipeline. This is not a time-stamped preregistration. 2025 is a descriptive year slice, **not a genuinely untouched out-of-sample test**. The research was designed retrospectively in 2026. ## Prices, costs and denominator - Source: read-only SELECT queries against FlashAlpha's QuestDB archive. Options come from `options_spy_eod`, `options_qqq_eod`, `options_iwm_eod`; underlying closes from `stocks`; dividends from `corporate_actions`. - Per-symbol EOD views aggregate the last observation for each contract/day. Their `ts` labels the trading day at midnight and is **not an executable quote timestamp**. The view omits the last contributing timestamp. The archive uses Eastern wall-clock timestamps with a Z suffix: do not interpret those labels as actual UTC instants. - Underlying: last bid/ask at or before 16:00 stored Eastern clock, sampled daily. The original `dividend_yields.close_price` probe had missing IWM prices and was rejected as the analysis price source; it remains in raw/ for provenance only. - Midpoint scenario: mean of bid and ask, before commissions. Bid/ask scenario: buy at ask, sell at bid, at entry and exit; subtract assumed $0.65 per option contract per side. Stock overlays cross underlying bid/ask with zero assumed stock commission. - These are two execution scenarios. Crossing recorded spreads is not a guarantee of live execution or a worst-case loss bound. Additional slippage, impact, exchange fees, financing, borrow, collateral yield, taxes and assignment costs are omitted. - **Normalized P&L (basis points) = net dollar P&L / (100 × entry underlying midpoint) × 10,000.** A basis point is 0.01%. For a $500 ETF, 10 bps corresponds to $50 on a $50,000 reference notional. - This denominator is neither option premium nor buying power, maximum risk or account equity. Rankings compare descriptive P&L on a common reference notional, **not equal-risk returns**. No Sharpe ratio, annualized return or maximum drawdown is reported: this extract does not contain the full daily portfolio path. ## Filters and exclusions - Selected contracts must have positive, finite, uncrossed bid/ask quotes on signal, entry and exit. Zero-bid contracts are excluded even when an actual closing transaction might be possible. - Signal spread must be at most max($0.10, 30% of midpoint), and both displayed sizes must cover the leg quantity on each observed date. - Do not replace a selected contract when its future entry/exit quote is missing. Record a specific exclusion instead. That is still complete-case analysis: missing future quotes can bias the retained sample. - Reject duplicate legs and coincident-strike diagonals. Invalid underlying quotes exclude the entire window. No synthetic fills or modeled option marks are inserted. - Exclude a window spanning an ex-dividend date for stock overlays or any short call. Dividends and associated assignment are not modeled. This uses historical ex-dates as a scope exclusion, not a verified point-in-time trading signal. - **Early exercise/assignment remains possible outside those exclusions**, including short puts. All short-option results are quote-mark simulations under a no-early-assignment assumption. Wheel and long-running roll strategies are not computed. - The headline comparison is the intersection of eligible windows for six profiles. All strategies see the same 133 ETF-month windows, but ETF weights are unequal: SPY 54, QQQ 39, IWM 40. There are 65 distinct months. Quality and dividend filters make this a selected sample. - `strategy_summary.csv` uses each profile's own available windows and must not be presented as the same-cohort ranking. ## Uncertainty and interpretation The ranking sorts mean bid/ask-and-fee-adjusted normalized P&L over the common cohort. Approximate 95% intervals use 1,000 bootstrap resamples of complete calendar-month blocks, fixed seed 20260915. ETF observations within a month stay together. The intervals do not account fully for serial dependence, regime choice, method selection or execution/data bias. They are exploratory uncertainty ranges, not proof that adjacent ranks differ. The same-window underlying midpoint price change averages +93.6 bps before stock trading costs. This is a limited price-return reference, not a continuous buy-and-hold total-return benchmark. The sample does not establish that the options strategies beat holding the underlying or provide alpha. ## FlashAlpha signal frame `signals.csv` contains archived ATM IV, trailing 20-return realized volatility, their ratio, put25–call25 IV, put10–ATM-put IV and back-call50–front-call50 IV. IV is stored as a decimal. RV uses sample standard deviation of 20 log price returns × sqrt(252), only using prices at or before the signal day. Those raw price returns are not dividend adjusted. Invalid underlying quotes make RV unavailable. These columns are research ingredients for vol-carry, skew, tail-pricing and term-structure comparisons. **They do not replay or validate FlashAlpha's production endpoint scores.** Fix an entry filter before testing and compare against the same unconditional structure. The term proxy uses 50-delta calls and is not a full constant-maturity ATM curve. ## Files and fields | File | Row meaning and key fields | |---|---| | `windows.csv` | One scheduled ETF-month; window_id, symbol, signal/entry/exit dates and underlying midpoints. | | `trades.csv` | One completed strategy/window; trade_id, structure, dollar P&L, normalized P&L, stock component, contract count. | | `legs.csv` | One option leg; join by trade_id. Quantity >0 is long, <0 short. Expiry, strike, right, prior-day selection delta, all signal/entry/exit quotes and leg P&L. Prices are USD per share; leg P&L is USD including multiplier 100. | | `exclusions.csv` | One uncomputed strategy/window with its first failing reason. Do not silently count these as zero-P&L trades. | | `signals.csv` | One eligible signal window; decimal IV/RV and IV spreads. Empty fields mean unavailable, never zero. | | `strategy_summary.csv` | One profile on its own eligible sample; mean/median/worst/best trade P&L in bps, win rate as fraction, 2025 slice and uncertainty interval. | | `headline_ranking.csv` | Six profiles on exactly the shared cohort; descriptive_rank sorts mean_net_bps descending. | | `headline_by_year_symbol.csv` | Headline common cohort split by year and ETF; no mixing with unmatched profile samples. | | `source_quality.csv` | Extracted quote counts and invalid two-sided quote counts before selection; not a full exchange archive audit. | | `strategy_catalogue.json` | 50 tier 1–3 research entries: 22 calculated, 28 explicitly untested extension frames. No tier 4/5 entries. | | `manifest.json` | Dataset ID, sample size, assumptions, exact raw file SHA-256 hashes and source description. | | `verification.json` | Cash-flow, provenance, chronology, cohort and accounting checks. | | `timestamp_spotcheck.json` | Small deterministic check against original intraday records; not full freshness validation. | | `research_facts.json`, `quote_bank.json` | Machine-readable provenance and narrowly scoped quotable findings. No invented public URL or publication date. | ## Reproduction Python 3.13 standard library; no dependency install or application build. ```text python research.py analyze python research.py verify python prepare_publication.py ``` Those commands use local cached raw responses. To recollect missing extracts on an authorized FlashAlpha machine, `python research.py collect` uses the existing SSH host alias and SELECT-only queries. Existing caches are retained. `python research.py spotcheck` similarly reads the archive and caches its small check. No database writes, deployments or vendor backfills occur. ## Supporting references - [OIC: Options Assignment](https://www.optionseducation.org/referencelibrary/faq/options-assignment) explains early-assignment considerations, including dividends. - [Cboe: Disclosures and Disclaimers](https://www.cboe.com/global-disclaimers) explains why hypothetical results can differ from actual execution. - Local implementation reference: `FlashAlpha.Api/Controllers/StrategiesController.cs` and `EarningsController.cs` establish the existing FlashAlpha endpoint catalogue, not the profitability of these simulations. ## Audit revision 1.1 See [AUDIT.md](AUDIT.md) for offline reproduction, exact source row locators, publication guards and the boundaries of verification. Frozen protocol: `protocol.json`.