Forward-Factor Calendar Spread — User Manual

Last reviewed 2026-06-29 · ~15 min read · Live signal · Backtest

The Forward-Factor calendar spread is a long-vega, neutral-delta options structure that fires only when the front month is paying meaningfully more implied volatility than the forward IV between the front and back expirations. This manual walks you through the math, how to read the live signal, how to paper trade the structure, how to monitor open positions, how to interpret backtests, and what can go wrong. Educational only. Not financial advice.

1. What the strategy is

A calendar spread is an options structure where you sell one expiration and buy a later expiration at the same strike. You collect time decay on the short front leg while the long back leg holds its value, profiting if the underlying stays near the strike and implied volatility holds or rises into the back expiration.

The Forward-Factor variant of this trade adds a discipline: only enter when the front-month implied volatility is meaningfully richer than the forward implied volatility implied by the term structure between the two expirations. The Forward Factor (FF) is the precise number that measures how much richer.

The intuition: if the front month is pricing a lot of volatility but the longer-dated IV thinks the average volatility between today and the back expiration will be lower, you're being paid extra premium on the short front leg relative to the back-leg cost. That premium has to come from somewhere — market expectations of a near-term event (earnings, FOMC, geopolitical), term-structure dislocation, or simply a temporary supply/demand imbalance on near-dated contracts.

Trade structure: SELL 1 front-month ATM option, BUY 1 back-month ATM option, same strike, same option type (both calls or both puts). Net debit. Max loss = debit paid.

2. The math behind it

Implied variance is approximately additive across non-overlapping time intervals. That gives us a way to back out the implied volatility for the period between the front and back expirations:

σfwd2 · (T2 − T1) = σback2 · T2 − σfront2 · T1

Solving for the forward variance gives the forward IV:

σfwd = sqrt( (σback2·T2 − σfront2·T1) / (T2 − T1) )

Where T1 is the front DTE in years and T2 is the back DTE in years.

The Forward Factor itself is just the relative premium of front IV over forward IV:

FF = (σfront − σfwd) / σfwd

A default FF threshold of 0.16 means we only enter when the front-month IV is at least 16% above the forward IV. Higher thresholds = fewer signals, more conviction per signal. Lower thresholds = more signals, more noise.

All implied volatilities are solved from option mid prices using the Black-Scholes-Merton formula with a configurable risk-free rate (default 4.5% annualized) and zero dividend yield. The solver uses Newton-Raphson with a Brent bisection fallback for pathological cases. Greeks are computed in closed form from the same BSM model.

Why variance and not vol? Implied variance (vol squared, times time) is additive in the lognormal Black-Scholes world; implied volatility itself is not. Using variance gives the right forward IV without bias. This is the same machinery options market makers use to build term-structure curves.

3. When it works (and when it fails)

The Forward-Factor calendar is designed for specific market conditions. It is not a universal income trade.

Favorable conditions

Adverse conditions

Critical risk: If the underlying gaps aggressively in either direction (an earnings miss, an unexpected guide-down, a macro shock), the position can hit max loss very quickly. A 16% FF threshold does not guarantee a profitable trade — it only guarantees the trade entered with measurable IV richness.

4. Using the live signal page

The live signal page is at /strategies/forward-factor/. It has three regions:

Walkthrough — running your first signal

1
Type a ticker in the Underlying field. Letters auto-uppercase. Examples that work well: SPY, QQQ, IWM, AAPL, MSFT, NVDA, TSLA. Single-stock names with upcoming earnings often produce stronger signals.
2
Pick option type. Calls if you're modestly bullish or directionally neutral. Puts if you're modestly bearish or want negative-delta exposure. The math is symmetric; the difference is mainly delta sign and assignment-risk profile.
3
Set front DTE target / tolerance. Default 30 / 7 means we look for a front expiration 23-37 days out. Tighter tolerance = more selective, possibly no match. Looser = more matches but less control.
4
Set back DTE target / tolerance. Default 90 / 14 means we look 76-104 days out. The wider the front/back gap, the more forward-IV signal we can extract, but the larger the structure's net debit and vega exposure.
5
Set FF entry threshold. Default 0.16. Increase to 0.20+ for stronger conviction signals on event-driven names. Lower to 0.10 if you're scanning for any term-structure dislocation.
6
Set liquidity caps. Min OI (default 200), min daily volume (default 50), max bid-ask spread as fraction of mid (default 0.08 = 8%). These prevent the tool from suggesting structures you can't actually trade at the modeled prices.
7
Click Scan signal. The Worker fetches Polygon option snapshots, picks a common ATM strike present in both expirations (3rd-Friday monthlies preferred over weeklies), solves IVs from the live mid prices, computes forward IV and FF, and returns a result within 2-5 seconds.

5. Reading the signal output

The result panel always shows three blocks: the score card, the indicator grid, and either the trade ticket or an explanation of why no ticket fired.

Score card

The big number is the FF value to three decimal places. The status label below it tells you what the system thinks:

StatusColorMeaning
ENTER ✓GreenFF cleared the threshold and all liquidity caps passed. Trade ticket shown.
HOLDYellowFF positive but below your threshold. Wait or lower the threshold.
FILTEREDRedLiquidity caps failed — OI, volume, or spread too low to trade safely.
NO EXPIRATION MATCHGrayNo expirations exist in both your front and back DTE windows. Widen tolerances or pick a more active underlying.
NO STRIKE MATCHGrayNo common strike present in both expirations within ±5% of spot. Rare; try a higher-priced underlying.
IV UNAVAILABLEGrayPolygon could not return live IV and our solver failed. Often after-hours or thin chain.

Indicator grid

The indicator grid below the score shows the inputs to the calculation so you can sanity-check what the engine used:

Trade ticket

When status is ENTER, the trade ticket fires with:

Alerts

The yellow alerts box surfaces conditions that didn't block the signal but you should know about — for example: front leg has earnings within the trade window, back leg has an ex-dividend date inside the holding period, or the spread on one leg is above 5% of mid.

6. Opening a paper trade

If the signal fires with a positive net debit, the trade ticket includes an Open as paper trade button. Clicking it saves the position to your browser's localStorage under the key oit.ff.positions.

What gets saved per position:

No server, no account, no signup. Paper positions live entirely in your browser. Clearing site data, switching browsers, or using incognito will lose them. If you want positions to persist across devices, copy/paste the contents of your portfolio panel into a note — cloud sync for FF positions is not yet implemented.

7. Monitoring open positions

Below the result panel, the Open positions section shows every paper trade you've opened. Each row displays:

Clicking Monitor

The Monitor button calls the Worker's /api/ff/monitor endpoint with the position's ticker, strike, expirations, and opening debit. The Worker:

  1. Fetches live spot.
  2. Fetches live snapshots for both legs.
  3. Computes the current bid-ask mids (with a quarter-spread penalty applied to model realistic close fills).
  4. Computes current MTM (mark-to-market): (back_mid - front_mid) - opening_debit.
  5. Computes current greeks, current IVs, current front DTE.
  6. Evaluates exit triggers and returns a recommendation.

Recommendations

RecommendationColorWhen it fires
holdNonePosition is within normal bounds. No action needed yet.
ROLL NOWYellowFront DTE ≤ 5 days. Time decay on the short leg is accelerating; either close or roll the front leg out.
CLOSE NOWRedProfit target hit (default 30% of debit), stop loss hit (default 40% of debit), or short leg is ITM by ≥ 1% of strike (assignment risk).

Triggers

The triggers array in the monitor response can include:

8. Closing positions and triggers

Each open position row has two action buttons:

Close

Clicking Close prompts for the realized P&L in dollars. If you've just clicked Monitor, the prompt pre-fills with the current MTM, but you can override it with the actual fill price from your broker (or a paper-fill estimate accounting for spread). It then asks for the outcome: closed (manually closed), expired (let both legs expire), assigned (short leg was assigned and you took stock or paid out), or rolled (you closed both and reopened a new structure).

The position's status changes from "open" to your chosen outcome. The realized P&L is added to the portfolio's lifetime total at the top of the panel. Closed positions stay in the panel for reference until you delete them.

Delete

Closed positions show a Delete button instead of Monitor + Close. Clicking it confirms and removes the position from localStorage permanently. Use this to clean up after a few months; there's no automatic prune.

Best practice: Re-monitor every position at least once per trading day until you close it. Calendars are sensitive to vol crush, earnings, and ex-div events that monitor will surface as triggers. The signal that opens the trade is half the work; the monitor that exits it is the other half.

9. Using the backtest page

The backtest page is at /strategies/forward-factor/backtest/. It runs a rapid 12-week historical study (configurable 4-26 weeks) and shows you how the same FF rules would have performed on weekly Monday entries.

How it works under the hood

For each Monday in the lookback window, the Worker:

  1. Fetches the underlying's daily close on that Monday.
  2. Queries Polygon for option contracts that were listed as of that Monday, filtered to the front/back DTE windows and to strikes within ±5% of spot.
  3. Prefers 3rd-Friday monthly expirations; picks the front and back closest to your DTE targets.
  4. Finds a common ATM strike present in both expirations.
  5. Pulls each leg's daily close on that Monday (used as the entry mid).
  6. Solves IVs, computes forward IV and FF.
  7. If FF clears the threshold and net debit is positive, records the entry.
  8. Pulls daily closes at exit (+5 business days, or 1 day before front expiration, whichever sooner).
  9. Computes realized P&L = (back_close_exit − front_close_exit) − net_debit_at_entry.

Backtest results are cached in KV for 24 hours per unique config, so re-running the same parameters is instant after the first call.

Walkthrough — running your first backtest

1
Type a ticker, choose option type, weeks back (4-26).
2
Set DTE targets / tolerances matching how you'd run the live signal.
3
Set FF threshold and hold days — both should reflect your real-world entry rule.
4
Click Run backtest. First run takes 15-45 seconds depending on Polygon cache hits. Subsequent runs of identical config return cached results instantly.

10. Interpreting backtest results

The results panel shows three sections in addition to the stats grid:

Stats grid

Equity curve

The SVG line shows cumulative P&L per trade in chronological order. Green dots mark wins, red dots mark losses. A clean upward slope with mostly green dots suggests the rule held in this regime; chop or a single big jump tells you the result is noise.

Trade log

The trade table shows every closed trade with entry/exit dates, the strike picked, both expirations, the FF at entry, the net debit, and the resulting P&L. Look for: clustering of wins/losses around macro events, FF range that produced winners, and whether back-month length correlates with outcome.

Skipped weeks

The expandable details section lists every week that did not fire a trade, grouped by reason: no_trade_ff_low means FF was positive but below threshold, no_contracts means Polygon had no listings in your DTE windows, no_expiration_pair means we couldn't find both a front and back match, etc. High skip rates suggest your DTE windows or threshold are misconfigured for this ticker.

Backtest caveats (mandatory reading):
  • No spread, slippage, or commissions modeled. Real fills will be worse than closes-as-mids by 5-20% of the structure value.
  • Survivorship bias possible. Polygon's contracts list returns contracts that existed; delisted weeks are silently dropped from skipped_weeks.
  • One ticker, one window, <30 trades = not statistical evidence. Use this to invalidate bad ideas, not to validate good ones.
  • Past performance is not predictive. Rules that worked in calm regimes can fail in vol shocks.

11. Risk disclosures

Strategy-specific risks

Tool-specific risks

Regulatory and legal

12. Frequently asked questions

Why does the signal sometimes return "no_expiration_match" for liquid tickers like SPY?

The Polygon contracts list filter is bounded by your DTE windows AND a ±5% strike band around spot. If your windows are tight (e.g., front 30/3 and back 90/3) the intersection may be empty on a given day. Try widening tolerance to 7 days for front and 14 days for back, which is the default.

Why is the trade ticket showing $0 debit and "Cannot open: non-positive debit"?

One or both legs have missing or stale quotes. This is common outside US market hours when Polygon's snapshot endpoint returns last-traded values from days ago. Re-run during regular market hours (9:30 AM - 4:00 PM ET).

What's the difference between FF and just "vol skew"?

Vol skew is the strike-to-strike IV difference at a single expiration. FF is the expiration-to-expiration IV difference at the same strike (specifically, front IV relative to the forward IV implied by the term structure). They're orthogonal measurements; a stock can have rich skew and zero FF, or vice versa.

Can I customize the profit target and stop loss for the monitor?

Yes, via the API directly — POST /api/ff/monitor accepts profit_target_pct_of_debit (default 0.30 = 30%) and stop_loss_pct_of_debit (default 0.40 = 40%). The UI does not yet expose these; the defaults are appropriate for most users.

How is forward IV different from forward rate?

Forward rate (or forward price) is what the market thinks the underlying will be worth at a future date, derived from interest rates and dividend yield. Forward IV is what the market thinks the average volatility will be between two future dates, derived from option prices at those dates. They're different financial quantities solving different problems.

Why does the backtest sometimes show a "skipped week" reason of "no_entry_prices"?

The Polygon daily-bar endpoint occasionally returns nothing for thinly-traded option contracts on specific dates. We skip those weeks rather than guess prices — the alternative would be inserting fabricated fills into the result, which would be worse than reporting fewer trades.

Can I run the backtest on past dates further back than 26 weeks?

Not in Phase 3a (the current in-Worker rapid backtest). The 26-week cap is set to keep Polygon API calls bounded and to fit within the Worker's CPU/wallclock budget per request. Phase 3b (deferred, multi-year backtest on Cloud Run with R2 storage) will lift this when shipped.

What if I disagree with the system's recommendation to close?

The recommendation is advisory. The triggers are objective rules; the close decision is yours. If you're holding through earnings deliberately, override the front_dte_threshold_hit trigger; if you have conviction the underlying will revert, override profit/loss targets. Just write down your reasoning — ad-hoc overrides without a thesis are how strategies decay.

Is the strategy patentable or proprietary?

No. Forward variance pricing and term-structure trades are well-known in options literature (Carr, Madan, Demeterfi, and others). This tool's contribution is packaging the math into a free, transparent, end-to-end workflow with paper trading and rapid backtest — not the underlying strategy itself.

Does Open as paper trade reserve any capital?

No. There is no balance, no account, no margin check. Paper trades are purely informational records. If you want to simulate an account-level paper portfolio with capital limits, use the dedicated paper trading page.

13. Glossary

Calendar spread (horizontal spread)
An options structure that sells one expiration and buys a later expiration at the same strike. Net debit. Long vega, near-zero delta when ATM, positive theta on the short leg net of negative theta on the back leg.
Implied volatility (IV)
The volatility input to the Black-Scholes-Merton formula that, when plugged in along with strike, spot, time, and rate, returns the option's market price. Quoted as an annualized decimal (0.25 = 25%).
Forward implied volatility
The implied volatility for the period between two future expirations, backed out from the two expirations' IVs using variance additivity. The fair forward IV is the market's expectation of the average vol over that interval.
Forward Factor (FF)
Defined as (front_iv - forward_iv) / forward_iv. Measures how much richer the front-month IV is than the forward IV. Positive FF indicates a sell-the-front, buy-the-back opportunity.
DTE (days to expiration)
Calendar days from the current date until an option's expiration date.
3rd-Friday monthly
The standard US equity option expiration cycle is the third Friday of each month. These contracts typically have the deepest liquidity. Weekly and quarterly expirations exist but tend to have wider spreads.
Net debit
The net cost to enter a multi-leg structure, calculated as premiums paid minus premiums received. For a long calendar, net debit equals back-leg ask minus front-leg bid (or modeled mids if using a calculator).
Max loss
The maximum dollar amount that can be lost on a position. For a long calendar held to front expiration and closed cleanly, max loss equals the net debit paid plus any commissions.
Delta, Gamma, Theta, Vega
The four primary option greeks. Delta = sensitivity to spot move; Gamma = how delta changes with spot; Theta = time decay per day; Vega = sensitivity to a 1-percentage-point IV change.
Variance additivity
The property that implied variance (vol squared times time) is approximately additive across non-overlapping time intervals in the Black-Scholes lognormal model. This is what lets us back out forward IV from front and back IV.
BSM (Black-Scholes-Merton)
The closed-form option pricing formula assuming lognormal price evolution, continuous trading, and no arbitrage. Despite well-known limitations (constant vol assumption, no jumps, etc.), it remains the industry-standard pricing baseline.
Newton-Raphson / Brent bisection
Two numerical methods used together to solve for implied volatility from a market option price. Newton-Raphson is fast when it converges; Brent bisection is the slower but reliable fallback for pathological cases.
Polygon
The third-party market data provider used by OptionIncomeTools for option chains, snapshots, and historical aggregates. We use Polygon's 15-minute-delayed free tier for live signals and the historical aggregates endpoint for the backtest.
localStorage
A browser-native key-value store that persists across page reloads and tab closures, but is scoped to a single origin and is wiped if the user clears site data. Used here to store paper positions client-side without any server roundtrip.
KV (Cloudflare Workers KV)
The eventually-consistent key-value cache on Cloudflare's edge used by our Worker to memoize Polygon responses and backtest results. Reads from KV are sub-millisecond; writes propagate globally within ~30 seconds.

Ready to try it?

Run a live signal on SPY first — it's the most liquid ticker and the most stable test case. Then try a single-stock name with upcoming earnings for a stronger FF reading.

Run live signal › See 12-week backtest ›