Own the underlying and sell an OTM call to collect premium, capping upside.
| Symbol | Return % | Sharpe | Max DD % | Win % | Avg/trade % | Trades |
|---|---|---|---|---|---|---|
| SPY | +36.2% | 0.46 | +13.4% | +84.2% | +1.9% | 19 |
| QQQ | +42.8% | 0.48 | +16.4% | +79.0% | +2.3% | 19 |
| IWM | +13.9% | 0.14 | +23.4% | +63.2% | +0.7% | 19 |
| DIA | +21.0% | 0.30 | +14.6% | +73.7% | +1.1% | 19 |
| Avg | +28.5% | 0.35 | +17.0% | +75.0% | — | 19 |
What this shows: Overlayed cumulative return series for this strategy across all available symbols.
How to read it: Look for symbols with smoother curves and faster recoveries to assess whether performance is broad-based or driven by a few outliers.
What this shows: Single-symbol cumulative return path for SPY.
How to read it: Use this detailed view to inspect entry/exit behavior over time and whether drawdowns cluster in specific periods.
| Parameter | Default | Description |
|---|---|---|
| strike_pct | 1.02 | Strike as fraction of spot (2% OTM) |
| dte | 45 | Days to expiration at entry |
| cycle_days | 21 | Trading days between new positions |
A covered call owns the underlying asset and sells an out-of-the-money call against it. The premium collected reduces the cost basis and provides income. Upside is capped at the strike price. The strategy profits in flat-to-moderately-bullish markets and underperforms in strong rallies. Backtested with 45 DTE cycles at a strike of 102% of spot, rolling every 21 trading days. P&L combines stock movement (capped at strike) plus premium minus call payoff.
def run_covered_call(S, K, T, r, sigma):
"""
Covered Call: own stock, sell OTM call.
K: strike (102% of S)
"""
premium = black_scholes_call(S, K, T, r, sigma)
# At expiration:
# stock_pnl = min(S_exp, K) - S_entry
# call_payoff = max(0, S_exp - K)
# P&L = stock_pnl + premium - call_payoff
return premium
# Backtest loop
for entry in monthly_entries:
S = spot_at_entry
K = round(S * 1.02 / 5) * 5 # 2% OTM call
T = 45 / 365.25
premium = black_scholes_call(S, K, T, RISK_FREE_RATE, avg_iv)
S_exp = spot_at_expiry
stock_pnl = min(S_exp, K) - S
pnl = stock_pnl + premium - max(0, S_exp - K)
pnl_pct = pnl / S * 100