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 and calls traded
  • Open Interest: Outstanding options contracts
  • Historical Data: Track changes in options sentiment over time
  • Daily Updates: Fresh data every trading day
CoverageDetails
MarketsS&P 500, NASDAQ, NYSE
Data PointsVolume, open interest, ratios
Update FrequencyDaily
Historical Data2+ years
from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
# Get put/call data as DataFrame
df = fb.options.put_call("S&P 500", "AAPL", as_dataframe=True)
print(df.head())

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

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(market, ticker):
"""Generate contrarian signal from put/call ratio"""
data = fb.options.put_call(market, ticker)
if not data.get("putCallData"):
return None
latest = data["putCallData"][0]
ratio = latest["ratio"]
# Calculate 20-day average for context
ratios = [d["ratio"] for d in data["putCallData"][:20]]
avg_ratio = sum(ratios) / len(ratios)
std_dev = (sum((r - avg_ratio) ** 2 for r in ratios) / len(ratios)) ** 0.5
# 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("S&P 500", "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 ticker in tickers:
try:
data = fb.options.put_call("S&P 500", ticker)
if not data.get("putCallData"):
continue
latest = data["putCallData"][0]
ratio = latest["ratio"]
# Flag extremes
if ratio > 1.5 or ratio < 0.4:
unusual.append({
"ticker": ticker,
"ratio": ratio,
"signal": "high_puts" if ratio > 1.5 else "high_calls",
"date": latest["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['ticker']}: 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(market, ticker, days=20):
"""Analyze if options sentiment is getting more bullish or bearish"""
data = fb.options.put_call(market, ticker)
if not data.get("putCallData") or len(data["putCallData"]) < days:
return None
recent = data["putCallData"][:days//2]
older = data["putCallData"][days//2:days]
recent_avg = sum(d["ratio"] for d in recent) / len(recent)
older_avg = sum(d["ratio"] for d in older) / len(older)
change = ((recent_avg - older_avg) / older_avg) * 100
if change > 10:
trend = "increasingly_bearish"
elif change < -10:
trend = "increasingly_bullish"
else:
trend = "stable"
return {
"ticker": ticker,
"recent_avg": recent_avg,
"older_avg": older_avg,
"change_percent": change,
"trend": trend
}
trend = analyze_sentiment_trend("S&P 500", "AAPL")
print(f"Trend: {trend['trend']} (Change: {trend['change_percent']:.1f}%)")