Double Calendar Spread Strategy
At IV Rank ivr_max or less: a put calendar offset_pct below the price and a call calendar offset_pct above (front ~30 days, back ~60), when the front month's IV is at least iv_ratio × the back's. Take 25%, stop at half the debit, out before the front expires or if the price leaves the range.
Rules · the when / do flow, read-only until you make a copyShow flow
The strategy runs as 1 track side by side. Each day, the first rule whose conditions hold in each track acts.
1. Double calendar
- INLow IV and the front month not cheap: open both calendars
When:
book.open == 0andiv_rank <= ivr_maxDo: sell put (as pf)strike spot * (1 - offset_pct)dte dte_f (30)dte_min dte_f_min (21)dte_max dte_f_max (40)avoid_earnings 1strict 1; buy put (as pb)strike leg.pf.strikedte dte_b (60)dte_min dte_b_min (50)dte_max dte_b_max (80)strict 1require leg.pf.iv / new.iv >= iv_ratio; sell call (as cf)strike spot * (1 + offset_pct)expiry leg.pf.expirystrict 1; buy call (as cb)strike leg.cf.strikeexpiry leg.pb.expirystrict 1 - TPtake_pct of the debit made: close
When:
book.pnl_pct >= take_pctDo: close pf; close pb; close cf; close cb - SLHalf the debit lost: close
When:
book.pnl_pct <= -stop_pctDo: close pf; close pb; close cf; close cb - MVPrice left the range: close
When:
spot <= leg.pf.strike * (1 - move_pct) or spot >= leg.cf.strike * (1 + move_pct)Do: close pf; close pb; close cf; close cb - EXFront month nearly done: close
When:
leg.pf.dte <= exit_dteDo: close pf; close pb; close cf; close cb - Closed or expired
When:
book.open == 0Do: nothing (hold)
Parameters and defaults
Every named number in the rules can be changed in the Rule Builder. These are the defaults the backtest used.
| Parameter | Default |
|---|---|
ivr_max | 40 |
offset_pct | 0.03 |
dte_f | 30 |
dte_f_min | 21 |
dte_f_max | 40 |
dte_b | 60 |
dte_b_min | 50 |
dte_b_max | 80 |
iv_ratio | 1 |
take_pct | 25 |
stop_pct | 50 |
exit_dte | 5 |
move_pct | 0.02 |
Make a copy to change any of it and run your own backtest.
At IV Rank ivr_max or less: a put calendar offset_pct below the price and a call calendar offset_pct above (front ~30 days, back ~60), when the front month's IV is at least iv_ratio × the back's. Take 25%, stop at half the debit, out before the front expires or if the price leaves the range.
What it is
When IV Rank is 40 or less, open a put calendar 3% below the price and a call calendar 3% above (front about 30 days, back about 60), when the front month's IV is at least the back month's. Take 25% of the debit, stop at half the debit, and close if the price leaves the range or the front month is nearly done.
When to use it
Use it when you expect a quiet stock and low, rising implied volatility: a wider profit range than a single calendar.
Maximum risk
The most you can lose is the debit paid for both calendars.
SPY backtest
Double calendar at its default settings on SPY, each period ending Nov 4, 2026. Returns are on the capital the strategy needed at its peak (collateral and cash), including interest on idle cash.
| Period | Total return | CAGR | Max drawdown | Win rate | SPY buy & hold | Capital |
|---|---|---|---|---|---|---|
| Since Feb 2024 | +580.4% | +100.4% | −20.4% | +55.4% (224) | +56.7% | $1,000 |
| 1 year | +106.1% | +106.1% | −31.8% | +54.8% (84) | +13.6% | $2,000 |
Win rate: share of option positions closed or expired at a profit (count in brackets). SPY buy & hold: the same capital in SPY shares, price only, no dividends. Hypothetical results, not a forecast. Change the settings, ticker or dates in the Rule Builder and run your own.
The rules
The strategy runs as 1 track side by side. Each day, the first rule whose conditions hold in each track acts.
1. Double calendar
- INLow IV and the front month not cheap: open both calendars
When:
book.open == 0andiv_rank <= ivr_maxDo: sell put (as pf)strike spot * (1 - offset_pct)dte dte_f (30)dte_min dte_f_min (21)dte_max dte_f_max (40)avoid_earnings 1strict 1; buy put (as pb)strike leg.pf.strikedte dte_b (60)dte_min dte_b_min (50)dte_max dte_b_max (80)strict 1require leg.pf.iv / new.iv >= iv_ratio; sell call (as cf)strike spot * (1 + offset_pct)expiry leg.pf.expirystrict 1; buy call (as cb)strike leg.cf.strikeexpiry leg.pb.expirystrict 1 - TPtake_pct of the debit made: close
When:
book.pnl_pct >= take_pctDo: close pf; close pb; close cf; close cb - SLHalf the debit lost: close
When:
book.pnl_pct <= -stop_pctDo: close pf; close pb; close cf; close cb - MVPrice left the range: close
When:
spot <= leg.pf.strike * (1 - move_pct) or spot >= leg.cf.strike * (1 + move_pct)Do: close pf; close pb; close cf; close cb - EXFront month nearly done: close
When:
leg.pf.dte <= exit_dteDo: close pf; close pb; close cf; close cb - Closed or expired
When:
book.open == 0Do: nothing (hold)
Parameters and defaults
Every named number in the rules can be changed in the Rule Builder. These are the defaults the backtest used.
| Parameter | Default |
|---|---|
ivr_max | 40 |
offset_pct | 0.03 |
dte_f | 30 |
dte_f_min | 21 |
dte_f_max | 40 |
dte_b | 60 |
dte_b_min | 50 |
dte_b_max | 80 |
iv_ratio | 1 |
take_pct | 25 |
stop_pct | 50 |
exit_dte | 5 |
move_pct | 0.02 |
Questions
Why only from February 2024?
Calendars depend on the gap between front- and back-month IV, which needs real option prices; those start in February 2024.
Why low IV Rank?
Calendars are long volatility: they gain if IV rises, so they are best opened when it is low.
How is it different from one calendar?
Two strikes spread the profit range wider, at about twice the cost.