Sell an OTM put and collect premium. Obligated to buy the underlying at the strike if assigned.
| Symbol | Return % | Sharpe | Max DD % | Win % | Avg/trade % | Trades |
|---|---|---|---|---|---|---|
| SPY | +44.9% | 1.31 | +5.3% | +94.7% | +2.4% | 19 |
| QQQ | +57.7% | 1.18 | +7.7% | +94.7% | +3.0% | 19 |
| IWM | +54.5% | 0.98 | +9.4% | +94.7% | +2.9% | 19 |
| DIA | +24.2% | 0.95 | +4.3% | +94.7% | +1.3% | 19 |
| Avg | +45.3% | 1.10 | +6.7% | +94.7% | — | 19 |
| Parameter | Default | Description |
|---|---|---|
| strike_pct | 0.95 | Strike as fraction of spot (5% OTM) |
| dte | 45 | Days to expiration at entry |
| cycle_days | 21 | Trading days between new positions |
A cash-secured put sells an out-of-the-money put option and holds cash equal to the strike price as collateral. The maximum profit is the premium collected; the maximum loss is the strike minus premium (if the underlying goes to zero). The strategy profits when the underlying stays above the strike at expiration. It is equivalent to a covered call in terms of risk/reward and is commonly used to acquire stock at a discount or generate income in neutral-to-bullish markets. Backtested using 45 DTE cycles, rolling every 21 trading days, with strikes at 95% of spot.
def run_cash_secured_put(S, K, T, r, sigma):
"""
Cash-Secured Put: sell OTM put, collect premium.
S: spot price, K: strike (95% of S), T: time to expiry (years)
r: risk-free rate, sigma: implied volatility
"""
premium = black_scholes_put(S, K, T, r, sigma)
# At expiration:
# P&L = premium - max(0, K - S_exp)
# Max profit = premium (if S_exp >= K)
# Max loss = K - premium (if S_exp = 0)
return premium
# Backtest loop (45 DTE, monthly cycles)
for entry in monthly_entries:
S = spot_at_entry
K = round(S * 0.95 / 5) * 5 # 5% OTM put
T = 45 / 365.25
premium = black_scholes_put(S, K, T, RISK_FREE_RATE, avg_iv)
S_exp = spot_at_expiry
pnl = premium - max(0, K - S_exp)
pnl_pct = pnl / K * 100 # as % of collateral