Skip to content

Put/Call Ratio Dataset

Access options market data including put/call ratios. Track options positioning and market sentiment derived from derivatives activity for systematic trading strategies.

The Put/Call Ratio dataset provides:

  • Put/Call Ratio: Ratio of put volume to call volume
  • Volume Data: Total puts, calls, and combined volume traded
  • Price: Underlying asset price at time of observation
  • Historical Data: Track changes in options sentiment over time
  • Daily Updates: Fresh data every trading day
CoverageDetails
MarketsS&P 500, NASDAQ, NYSE
Data PointsVolume, ratios, price
Update FrequencyDaily
Historical Data2+ years
from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
df = fb.options.put_call("AAPL", as_dataframe=True)
print(df)

For complete code examples in Python, JavaScript, C++, Rust, and cURL, see the API Reference.

Plot put/call ratio trends with the built-in SDK chart:

from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
# One-line interactive options chart (stacked volume bars + ratio line)
fb.plot.options("NVDA")
Options Put/Call Chart
NVDA put/call ratio over time
RatioInterpretationSignal
> 1.2Excessive put buyingContrarian bullish (fear may be overdone)
1.0 - 1.2Elevated put activityBearish sentiment
0.7 - 1.0Normal rangeNeutral
0.5 - 0.7Elevated call activityBullish sentiment
< 0.5Excessive call buyingContrarian bearish (euphoria may be overdone)

Open interest ratios show longer-term positioning:

  • Rising OI Ratio: Increasing hedging/bearish positioning
  • Falling OI Ratio: Decreasing hedges/bullish positioning
  • Stable OI Ratio: Consistent market positioning

Use extreme put/call readings as contrarian signals:

from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
def get_contrarian_signal(symbol):
"""Generate contrarian signal from put/call ratio"""
df = fb.options.put_call(symbol, as_dataframe=True)
if df.empty:
return None
ratio = df["ratio"].iloc[0]
# Calculate 20-day average for context
ratios = df["ratio"].head(20)
avg_ratio = ratios.mean()
std_dev = ratios.std()
# Z-score
z_score = (ratio - avg_ratio) / std_dev if std_dev > 0 else 0
if z_score > 2:
return {"signal": "contrarian_buy", "z_score": z_score, "ratio": ratio}
elif z_score < -2:
return {"signal": "contrarian_sell", "z_score": z_score, "ratio": ratio}
else:
return {"signal": "neutral", "z_score": z_score, "ratio": ratio}
signal = get_contrarian_signal("AAPL")
print(f"Signal: {signal['signal']} (Z-score: {signal['z_score']:.2f})")

Screen for unusual options activity:

from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
def scan_unusual_options(tickers):
"""Find stocks with unusual put/call ratios"""
unusual = []
for symbol in tickers:
try:
df = fb.options.put_call(symbol, as_dataframe=True)
if df.empty:
continue
ratio = df["ratio"].iloc[0]
date = str(df.index[0])
# Flag extremes
if ratio > 1.5 or ratio < 0.4:
unusual.append({
"symbol": symbol,
"ratio": ratio,
"signal": "high_puts" if ratio > 1.5 else "high_calls",
"date": date
})
except Exception:
continue
return sorted(unusual, key=lambda x: abs(x["ratio"] - 1), reverse=True)
tickers = ["AAPL", "MSFT", "GOOGL", "AMZN", "NVDA", "META", "TSLA"]
unusual = scan_unusual_options(tickers)
for u in unusual:
print(f"{u['symbol']}: P/C Ratio {u['ratio']:.2f} - {u['signal']}")

Track how options sentiment is changing:

from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
def analyze_sentiment_trend(symbol, days=20):
"""Analyze if options sentiment is getting more bullish or bearish"""
df = fb.options.put_call(symbol, as_dataframe=True)
if df.empty or len(df) < days:
return None
recent_avg = df["ratio"].head(days // 2).mean()
older_avg = df["ratio"].iloc[days // 2:days].mean()
change = ((recent_avg - older_avg) / older_avg) * 100
if change > 10:
trend = "increasingly_bearish"
elif change < -10:
trend = "increasingly_bullish"
else:
trend = "stable"
return {
"symbol": symbol,
"recent_avg": recent_avg,
"older_avg": older_avg,
"change_percent": change,
"trend": trend
}
trend = analyze_sentiment_trend("AAPL")
print(f"Trend: {trend['trend']} (Change: {trend['change_percent']:.1f}%)")