SPY / IWM Covered-Call / Short-Call Overlay Backtester

ORATS same-source strikes data. Choose SPY or IWM, then compare ETF-only vs ETF + covered-call/short-call overlay with warehouse prices and a Black-Scholes vol-parameter model using the same strike rows.
Leave blank for latest available data.

Note: max active contracts caps overlap; it does not multiply each trade. Daily option MTM uses ORATS marks when available, otherwise carries forward the previous mark. Phase 1 total-return accounting credits ETF dividends as cash on ex-date and compounds dividend cash plus option-premium cash at the historical/FRED risk-free cash rate when available. Early assignment around ex-dividend is not modeled yet. Risk metrics use daily portfolio-value returns.

Running warehouse and vol-model backtests…

Side-by-side ratios

Warehouse ORATS marks, vol-model pricing, and ETF-only benchmark on the same rows. A dot plus underline marks the best value; max drawdown highlights the smallest drawdown.

Portfolio P/L chart

Plotted lines: warehouse covered-call book, vol-model covered-call book, ETF-only benchmark, and short-call exposure as % of ETF exposure.
No run yet

Open contracts / current market value

Recent kept trades

Ratios & metrics explained

Definitions use daily mark-to-market portfolio values. Covered-call means long ETF units plus short-call overlay. Warehouse uses ORATS option marks when available; vol model reprices the same selected strikes with Black-Scholes inputs.

Warehouse vs vol-model process

Shared steps: same dates, signal, ORATS candidate rows, target delta/DTE, IV>RV filter, max-active cap, contract size, expiry intrinsic settlement, ETF dividend ledger, cash sweep, and risk metrics. Warehouse: uses the stored ORATS candidate price/mark for entry and daily short-call liability. Vol model: uses the same selected ORATS row, but replaces option price/mark with Black-Scholes-Merton using row spot, strike, DTE, IV, and the dashboard r/q inputs.

If the trade set is identical, warehouse-vs-vol P/L differences come from option valuation and daily MTM marks, not strategy timing or settlement.

Mathematical differences beyond r/q

Warehouse price_t = ORATS stored price/mid/mark_t Vol price_t = BSM_call(S_t, K, T_t, IV_t, r, q) BSM call = S*e^(-qT)*N(d1) - K*e^(-rT)*N(d2) d1 = [ln(S/K) + (r - q + 0.5*IV^2)T] / (IV*sqrt(T)) d2 = d1 - IV*sqrt(T)

Apart from r/q, the warehouse path is an observed/vendor-smoothed listed-contract value; the vol path is a plain European BSM reprice. Residual differences can come from ORATS smoothing/curve calibration, bid-mid-price conventions, American ETF option features, borrow/forward assumptions not exposed as r/q, day-count/DTE conventions, and mark fallback/averaging rules. Delta selection still uses ORATS actual delta in both paths; the vol model does not re-select strikes from its own model delta.

Total return

R_total = V_end / V_start - 1

End-to-end portfolio return over the selected backtest range.

Final P/L

P/L = V_end - V_start

Dollar gain/loss for the full portfolio. Overlay P/L isolates short-call premium and mark-to-market effects.

Daily return

r_t = V_t / V_{t-1} - 1

The input series for Sharpe, Sortino, volatility, beta, alpha, and information ratio.

CAGR

CAGR = (V_end / V_start)^(1 / years) - 1

Annualized growth rate using calendar days divided by 365.25.

Annualized volatility

Vol_ann = stdev(r_t) * sqrt(252)

Sample standard deviation of daily returns, annualized with 252 trading days.

Sharpe ratio

Sharpe = mean(r_t - rf_daily) / stdev(r_t - rf_daily) * sqrt(252)

Risk-adjusted excess return. rf_daily is derived from the configured annual risk-free rate.

Sortino ratio

Sortino = mean(r_t - target_daily) / downside_dev * sqrt(252)
downside_dev = sqrt(mean(min(0, r_t-target_daily)^2))

Like Sharpe but only penalizes downside deviations below the target/risk-free rate.

Max drawdown

DD_t = V_t / max(V_0...V_t) - 1
Max DD = min(DD_t)

Largest peak-to-trough portfolio loss; displayed as a negative percentage.

Calmar ratio

Calmar = CAGR / abs(Max DD)

Return per unit of worst drawdown. Higher is better.

Information ratio vs ETF

IR = mean(r_strategy - r_ETF) / stdev(r_strategy - r_ETF) * sqrt(252)

Consistency of active return versus the ETF-only benchmark.

Beta vs ETF

Beta = cov(r_strategy, r_ETF) / var(r_ETF)

Sensitivity of the strategy to ETF daily returns.

Alpha vs ETF

Alpha_ann = [(mean(r_strategy)-rf_daily) - Beta*(mean(r_ETF)-rf_daily)] * 252

Annualized residual return after controlling for ETF beta.

Open short liability

Liability = current option mark * 100 * contracts

Current estimated cost to buy back open short calls.

Unrealized P/L

Unrealized = premium_received - current_short_liability

Mark-to-market P/L on open short-call contracts before expiration/close.

IV/RV filter

Keep trade when entry_IV > RV_lookback

Optional filter comparing ORATS entry implied volatility to realized volatility over the chosen lookback window.

Cash sweep / risk-free proxy

cash_t = cash_{t-1} * (1 + rf_daily) + inflows - outflows

Phase 1 compounds ETF dividend cash and option-premium cash at the FRED 3M T-bill daily cash-return proxy when available, with manual risk-free rate as fallback.

ETF dividends

dividend_cash = long_shares * dividend_per_share

ETF dividends are credited on ex-date to the long ETF cash ledger and then swept into the risk-free cash proxy. Early assignment before ex-dividend is not modeled in Phase 1.

Worst trade

min(pnl_dollars_1_contract)

Worst realized/expired short-call trade in dollars for one contract.