Skip to content

Directional Bias Analysis Guide

Overview

The expected move from straddle pricing tells you how much the stock might move, but not which direction. This guide explains how to predict directional bias using market signals.

The Problem

Expected Move Example: - NVDA has an 8.5% expected move - Could move to: $140.75 (-8.5%) OR $147.75 (+8.5%) - Which direction is more likely?

The Solution: Multi-Signal Analysis

We analyze multiple market indicators to determine if the stock is more likely to move up or down:

1. Put/Call IV Skew (30% weight)

What it measures: Relative pricing of puts vs calls at ATM strikes

  • Positive skew (puts more expensive) = Bearish bias
  • Negative skew (calls more expensive) = Bullish bias
  • Why it works: Market makers price in expected direction

Example:

Put IV: 0.55, Call IV: 0.50 → Skew = +0.05 (BEARISH)
Put IV: 0.50, Call IV: 0.55 → Skew = -0.05 (BULLISH)

2. Put/Call Volume Ratio (25% weight)

What it measures: Trading activity in puts vs calls

  • Ratio > 1.2: More put buying (bearish bias)
  • Ratio < 0.8: More call buying (bullish bias)
  • Why it works: Traders position for expected moves

Example:

Put volume: 5000, Call volume: 10000 → Ratio = 0.5 (BULLISH - heavy call buying)

3. Put/Call Open Interest Ratio (20% weight)

What it measures: Outstanding positions in puts vs calls

  • Ratio > 1.2: More put positions (bearish bias)
  • Ratio < 0.8: More call positions (bullish bias)
  • Why it works: Indicates longer-term positioning

4. Recent Price Trend (25% weight)

What it measures: Recent price momentum

  • Trend > 3%: Strong uptrend (bullish bias)
  • Trend < -3%: Strong downtrend (bearish bias)
  • Why it works: Momentum often continues into earnings

Usage

Method 1: Directional Analysis Script

uv run python scripts/directional_analysis.py NVDA

Output:

Directional Bias Signals:
  Put/Call IV Skew:        -0.0031  (Neutral)
  Put/Call Volume Ratio:   0.48     (Bullish - more call volume)
  Put/Call OI Ratio:       1.14     (Neutral)
  5-Day Price Trend:       +0.70%   (Neutral)

Overall Directional Bias: NEUTRAL
Confidence: 50%
Expected Directional Move: +0.95%

Strike Recommendation:
  Current Price:         $186.23
  Expected Move:         ±3.44%
  Suggested Strike:      $185.00
  Strike Adjustment:     -0.66%

Method 2: Programmatic Access

from trade_calc.data import fetch_options_data_yfinance
from trade_calc.directional_bias import analyze_directional_bias, suggest_strike_adjustment
import pandas as pd
import yfinance as yf

# Fetch data
options_data = fetch_options_data_yfinance("NVDA")
expiration = options_data["expirations"][0]
chain = options_data["options_chains"][expiration]

# Convert to DataFrames
calls_df = pd.DataFrame(chain["calls"])
puts_df = pd.DataFrame(chain["puts"])
current_price = options_data["current_price"]

# Get price history
stock = yf.Ticker("NVDA")
price_history = stock.history(period="1mo")

# Analyze
signals = analyze_directional_bias(calls_df, puts_df, current_price, price_history)

# Get strike suggestion
expected_move_pct = 8.5  # From calculator.py
strike_suggestion = suggest_strike_adjustment(current_price, expected_move_pct, signals)

print(f"Bias: {signals.overall_bias}")
print(f"Confidence: {signals.bias_confidence * 100:.0f}%")
print(f"Suggested Strike: ${strike_suggestion['suggested_strike']:.2f}")

Method 3: Integration with Monte Carlo

from scripts.monte_carlo import SimulationParams, CalendarSpreadSimulator
from trade_calc.directional_bias import analyze_directional_bias

# ... fetch data and analyze as above ...

# Create simulation with directional bias
params = SimulationParams(
    spot_price=186.23,
    strike_price=186.23,
    front_dte=7,
    back_dte=37,
    pre_earnings_iv=0.60,
    post_earnings_iv=0.30,
    back_month_pre_iv=0.40,
    back_month_post_iv=0.35,
    earnings_jump_mean=0.0,
    earnings_jump_std=0.05,
    drift_rate=0.0,
    risk_free_rate=0.05,
    num_simulations=5000,
    profit_target=0.25,
    expected_move_pct=8.5,
    # NEW: Add directional bias
    directional_bias=signals.overall_bias,  # "bullish", "bearish", or "neutral"
    directional_bias_pct=signals.bias_magnitude,  # e.g., +3.5% or -2.8%
    use_dynamic_strikes=True,  # Enable strike adjustment
)

simulator = CalendarSpreadSimulator(params)
results = simulator.run()

Signal Interpretation

Strong Bullish Bias

Put/Call IV Skew:      < -0.05  (Calls expensive)
Put/Call Volume:       < 0.8    (Heavy call buying)
Recent Trend:          > +3%    (Strong uptrend)

→ Suggest strike ABOVE current price
→ Example: $186 spot → $188-190 strike

Strong Bearish Bias

Put/Call IV Skew:      > +0.05  (Puts expensive)
Put/Call Volume:       > 1.2    (Heavy put buying)
Recent Trend:          < -3%    (Strong downtrend)

→ Suggest strike BELOW current price
→ Example: $186 spot → $182-184 strike

Neutral/Conflicting Signals

Mixed signals or low confidence

→ Stay ATM (at-the-money)
→ Calendar spreads profit from IV crush regardless of direction

Strike Adjustment Strategy

  • Use 50% of directional bias for strike adjustment
  • Cap adjustment at 50% of expected move
  • Round to nearest standard strike increment

Example:

Spot: $186
Expected Move: 8% (±$14.88)
Directional Bias: +4% bullish ($7.44)

Strike Adjustment:
  50% of bias: +$3.72
  Max allowed (50% of expected): $7.44
  Adjusted strike: $189.72 → Round to $190

Aggressive Approach

  • Use 100% of directional bias
  • Still cap at 50% of expected move
  • Higher risk/reward

Calendar Spread Considerations

Why Not Go Too Far OTM?

Calendar spreads have a sweet spot:

  1. ATM (0% OTM): Maximum extrinsic value
  2. Slight OTM (2-5%): Still good time value, directional tilt
  3. Far OTM (>10%): Much less time value, higher directional risk

Recommendation: Even with strong directional bias, stay within 5% of ATM

Example Scenarios

Scenario 1: Strong Bullish Signal, High Confidence

Spot: $186
Bias: Bullish, Confidence: 75%
Expected Move: 8.5%

Suggested Strike: $188-190 (1-2% OTM)
Rationale: Strong signal justifies slight OTM positioning

Scenario 2: Weak Bullish Signal, Low Confidence

Spot: $186
Bias: Bullish, Confidence: 35%
Expected Move: 8.5%

Suggested Strike: $186 (ATM)
Rationale: Low confidence → stay ATM for safety

Scenario 3: Conflicting Signals

Spot: $186
IV Skew: Bearish (-0.06)
Volume: Bullish (0.65)
Trend: Neutral (+1%)

Suggested Strike: $186 (ATM)
Rationale: Mixed signals → stick with ATM

Confidence Levels

The algorithm calculates confidence based on signal strength:

  • High (>60%): Multiple strong signals agree → Trust the bias
  • Medium (40-60%): Some signals agree → Use caution
  • Low (<40%): Weak or conflicting signals → Stay ATM

Limitations

1. No Crystal Ball

  • Directional bias is probabilistic, not predictive
  • Earnings can surprise either direction
  • Even 80% confidence means 20% chance of wrong direction

2. Calendar Spreads Are IV Plays

  • Primary profit driver is IV crush, not direction
  • Don't over-emphasize direction for this strategy
  • Slight OTM positioning is fine, far OTM is risky

3. Market Conditions

  • Signals less reliable in highly volatile markets
  • News/events can override technical signals
  • Always check earnings expectations and guidance

Best Practices

1. Combine with Fundamentals

# Get directional bias
uv run python scripts/directional_analysis.py TSLA

# Also check:
- Earnings estimate vs actual history
- Guidance expectations
- Sector trends
- Recent news/catalysts

2. Use Confidence Thresholds

if signals.bias_confidence > 0.6:
    # Trust the signal, adjust strikes
    use_bias = True
elif signals.bias_confidence > 0.4:
    # Medium confidence, small adjustment
    use_bias = True
    bias_pct = bias_pct * 0.5  # Reduce adjustment
else:
    # Low confidence, stay ATM
    use_bias = False

3. Monitor Multiple Expirations

# Check near-term and longer-term signals
uv run python scripts/directional_analysis.py NVDA --expiration 2026-01-23
uv run python scripts/directional_analysis.py NVDA --expiration 2026-02-20

Complete Workflow

Step 1: Analyze Stock

uv run python scripts/calculator.py
# Enter: NVDA
# Note: Expected Move: 8.5%

Step 2: Check Directional Bias

uv run python scripts/directional_analysis.py NVDA
# Note: Bias: Bullish, Confidence: 65%, Suggested Strike: $190

Step 3: Run Simulation

params = SimulationParams(
    spot_price=186,
    strike_price=190,  # From directional analysis
    expected_move_pct=8.5,  # From calculator
    directional_bias="bullish",  # From analysis
    directional_bias_pct=3.5,  # From analysis
    # ... other params
)

Step 4: Execute Trade

  • Enter position at suggested strike
  • Set profit target (e.g., 25% of max profit)
  • Monitor for large moves or stop loss triggers

Quick Reference

Indicator Bearish Threshold Neutral Range Bullish Threshold
IV Skew > +0.05 -0.05 to +0.05 < -0.05
Volume Ratio > 1.2 0.8 to 1.2 < 0.8
OI Ratio > 1.2 0.8 to 1.2 < 0.8
5-Day Trend < -3% -3% to +3% > +3%

Troubleshooting

Q: Signals are conflicting - what to do? A: Stay ATM. Calendar spreads don't require directional accuracy.

Q: High confidence bullish, but stock went down? A: Normal! 70% confidence means 30% chance of wrong direction. That's trading.

Q: Should I always follow the directional bias? A: No. Use it to inform strike selection, but don't ignore fundamentals or risk tolerance.

Q: Can I use this for other strategies? A: Yes! Directional bias applies to any options strategy. Adjust usage based on strategy type.

Further Reading

  • Options Market Signals: /trade_calc/directional_bias.py
  • Monte Carlo Integration: MONTE_CARLO_GUIDE.md
  • Strike Selection: configs/README.md