高いプット/コールレシオは強気シグナルですか
高いプット/コールレシオを強気と見る逆張りの考え方を検証します。個別株と指数オプションのパーセンタイル分布から、極端な水準の後に実際に何が起きたかを確認できます。
プット/コールレシオが高い場合、逆張りでは典型的な強気シグナルとされる。プットの買いが異例に膨らむと、市場参加者の多くがすでに下落に備えていると解釈されるためだ。ただし、この見方に基づいて行動する際には問題がある。「高い」ことを示す固定的な水準はなく、画面上の1.15という数値が、個別株オプションでは極端な水準である一方、指数商品では通常のセッションに相当することもある。
必要なのは、比較の基準となる分布だ。本ページでは、両方の市場について基準分布を示し、高い数値の後に何が起きたかを検証する。プット/コールレシオの解説では、レシオの算出方法を説明している。以下の内容はすべて、その定義を起点としている。
測定方法について、二点補足する。ここで扱うレシオはすべて、その日に取引された契約数を数えたものであり、出来高ベースのレシオである。建玉は未決済のポジションを数えるため、異なる概念となる(出来高と建玉で両者を区別している)。また、数値は市場全体ではなく、固定した銘柄群に基づいている。対象は代表的な個別株10銘柄と、広範な市場を対象とするETF 3銘柄である。そのため、最後の小数点以下ではなく、分布の形状を確認すべきだ。
高いput/callレシオとは
水準だけでは答えられない問いに、パーセンタイルが答えを与える。以下の曲線は、2022年1月から2026年7月までの全セッションを対象に、各ブックについてセッションごとに一つのレシオを示している。
各数値の背後にある正確なSQL
WITH book_days AS (
SELECT date AS day,
if(underlying_symbol IN ('SPY', 'QQQ', 'IWM'), 'index_etf', 'equity') AS book,
sumIf(volume, upper(substring(ticker, length(ticker) - 8, 1)) = 'P') AS put_volume,
sumIf(volume, upper(substring(ticker, length(ticker) - 8, 1)) = 'C') AS call_volume
FROM global_markets.options_greeks
WHERE date >= toDate('2022-01-01')
AND date <= toDate('2026-07-31')
AND volume > 0
AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'AAPL', 'MSFT', 'NVDA', 'AMZN',
'META', 'TSLA', 'GOOGL', 'JPM', 'KO', 'XOM')
GROUP BY day, book
HAVING call_volume > 0
),
paired AS (
SELECT day,
toFloat64(sumIf(put_volume, book = 'equity'))
/ toFloat64(sumIf(call_volume, book = 'equity')) AS equity_pcr,
toFloat64(sumIf(put_volume, book = 'index_etf'))
/ toFloat64(sumIf(call_volume, book = 'index_etf')) AS index_pcr
FROM book_days
GROUP BY day
HAVING sumIf(call_volume, book = 'equity') > 0
AND sumIf(call_volume, book = 'index_etf') > 0
),
curves AS (
SELECT arrayMap(v -> round(v, 2),
quantilesDeterministic(0.05, 0.10, 0.25, 0.50, 0.75, 0.90, 0.95, 0.99)
(equity_pcr, cityHash64(day))) AS eq,
arrayMap(v -> round(v, 2),
quantilesDeterministic(0.05, 0.10, 0.25, 0.50, 0.75, 0.90, 0.95, 0.99)
(index_pcr, cityHash64(day))) AS idx
FROM paired
)
SELECT z.1 AS percentile,
z.2 AS equity_pcr,
z.3 AS index_etf_pcr
FROM (
SELECT arrayJoin(arrayZip(['p05', 'p10', 'p25', 'p50', 'p75', 'p90', 'p95', 'p99'], eq, idx)) AS z
FROM curves
)単一銘柄バスケットでは、セッションの中央値はコール一枚当たり0.67枚のputだった。上位十分の一のセッションは0.89から始まり、最も極端な上位一%は1.34を上回った。静かな局面も基準づくりに同様に役立つ。二十セッションに一つは0.48以下で終えた。
ETFの分布は、曲線上のどの地点でも異なる。ETFのセッション中央値は1.45で、単一銘柄の中央値が大きく下回る一対一のラインを上回った。ETFの上位十分の一は1.77から始まった。ブックを明示せずに示されたレシオは、ほとんど意味を持たない。1.15というprintも、どの列の値かによって意味が異なる。
指数の比率が1を上回るのは正常で、個別株の比率が1を上回るのは正常ではない
同じ出来高を原資産別に分けると、数値は明確に分かれる。
各数値の背後にある正確なSQL
WITH symbol_days AS (
SELECT underlying_symbol AS symbol,
date AS day,
sumIf(volume, upper(substring(ticker, length(ticker) - 8, 1)) = 'P') AS put_volume,
sumIf(volume, upper(substring(ticker, length(ticker) - 8, 1)) = 'C') AS call_volume
FROM global_markets.options_greeks
WHERE date >= toDate('2026-01-01')
AND date <= toDate('2026-07-31')
AND volume > 0
AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'AAPL', 'MSFT', 'NVDA', 'AMZN',
'META', 'TSLA', 'GOOGL', 'JPM', 'KO', 'XOM')
GROUP BY symbol, day
HAVING call_volume > 0
)
SELECT symbol,
round(toFloat64(sum(put_volume)) / toFloat64(sum(call_volume)), 2) AS put_call_ratio,
round(100 * countIf(put_volume > call_volume) / count(), 1) AS above_one_pct,
count() AS observations
FROM symbol_days
GROUP BY symbol
ORDER BY put_call_ratio DESC2026年の最初の七カ月間、IWMはコール一枚当たりプット2.73枚で首位となり、144セッションのうち98.6%で1を上回った。最下位はXOMで、0.38となり、セッションの2.8%で1を上回った。
この差は構造的なものだ。広範な市場を対象とするETFオプションは、ポートフォリオのヘッジに使われる。二百銘柄を保有する運用会社は、保有銘柄すべてのプットを買うのではなく、指数プットを買う。その取引には、対応するコール売買がない。一方、個別株オプションの出来高は、上昇余地を狙って買われるコールや、すでに保有している株式に対して売られるコールに傾く。「total」比率は両方の取引を混ぜるため、数値は二つの中間になる。また、投資家心理だけでなく、その日の商品の構成によっても変動する。
もう一つ、数値の水準を押し上げる要因を把握しておきたい。指数とETFの出来高では、現在、当日満期の取引(0DTEオプション)が大きな割合を占めている。このカテゴリーは、従来の目安が設定された当時には、現在のような規模では取引されていなかった。構成が異なる市場のティッカーに、過去の水準をそのまま当てはめることはできない。
プット/コールレシオが高いと強気なのか。極端な水準の後に何が起きたか
逆張りの仮説は検証できる。各セッションを、その日の株式プット/コールレシオに基づいて五分位に分類し、その後の5セッションおよび20セッションでS&P 500連動商品がどのように動いたかを測定する。
各数値の背後にある正確なSQL
WITH raw AS (
SELECT date AS day,
sumIf(volume, upper(substring(ticker, length(ticker) - 8, 1)) = 'P') AS put_volume,
sumIf(volume, upper(substring(ticker, length(ticker) - 8, 1)) = 'C') AS call_volume
FROM global_markets.options_greeks
WHERE date >= toDate('2022-01-01')
AND date <= toDate('2026-07-31')
AND volume > 0
AND underlying_symbol IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'META',
'TSLA', 'GOOGL', 'JPM', 'KO', 'XOM')
GROUP BY day
HAVING call_volume > 0
),
equity_pcr AS (
SELECT day, toFloat64(put_volume) / toFloat64(call_volume) AS pcr
FROM raw
),
spy_daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS day,
toFloat64(argMax(close, window_start)) AS close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2022-01-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-08-01')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY day
),
forward AS (
SELECT day,
close,
any(close) OVER (ORDER BY day ASC ROWS BETWEEN 5 FOLLOWING AND 5 FOLLOWING) AS close_5,
any(close) OVER (ORDER BY day ASC ROWS BETWEEN 20 FOLLOWING AND 20 FOLLOWING) AS close_20
FROM spy_daily
),
joined AS (
SELECT p.day AS day,
p.pcr AS pcr,
100 * (f.close_5 / f.close - 1) AS fwd_5d_pct,
100 * (f.close_20 / f.close - 1) AS fwd_20d_pct
FROM equity_pcr AS p
INNER JOIN forward AS f ON p.day = f.day
WHERE f.close_5 > 0 AND f.close_20 > 0
),
cuts AS (
SELECT quantilesDeterministic(0.2, 0.4, 0.6, 0.8)(pcr, cityHash64(day)) AS q
FROM joined
)
SELECT multiIf(pcr < q[1], 'lowest fifth',
pcr < q[2], 'second fifth',
pcr < q[3], 'middle fifth',
pcr < q[4], 'fourth fifth',
'highest fifth') AS pcr_band,
count() AS observations,
round(min(pcr), 2) AS band_floor_ratio,
round(quantileDeterministic(0.5)(fwd_5d_pct, cityHash64(day)), 2) AS fwd_5d_median_pct,
round(quantileDeterministic(0.5)(fwd_20d_pct, cityHash64(day)), 2) AS fwd_20d_median_pct,
round(quantileDeterministic(0.25)(fwd_20d_pct, cityHash64(day)), 2) AS fwd_20d_p25_pct,
round(quantileDeterministic(0.75)(fwd_20d_pct, cityHash64(day)), 2) AS fwd_20d_p75_pct
FROM joined CROSS JOIN cuts
GROUP BY pcr_band
ORDER BY band_floor_ratio ASC最も落ち着いた五分位は0.34から始まり、最も活発な五分位は0.81から始まる。そのため、上位帯には逆張り投資家が過熱とみなす数値がすべて含まれる。これら226セッションでは、20セッション後の値動きの中央値は3%だった。最も落ち着いた五分位の後は0.91%だった。5セッション後では、同じ二つの帯がそれぞれ0.82%と0.3%だった。
中央値だけでは重要な部分が見えない。上位五分位では、20セッション後の結果の中央50%が-1.82%から5.71%の範囲に収まった。最も落ち着いた五分位では、中央50%が-0.83%から2.67%の範囲だった。両方の範囲はかなり重なっている。セッションがどの帯に入るかによって分布の中心は動くが、その中心を取り巻く範囲はほとんど狭まらない。これは経験則では捉えにくい部分である。
サンプルの重みについては注意が必要だ。2022年1月から2026年7月までは、弱気相場とその後の回復局面を一つずつ含み、各帯の観測数はおおむね226セッションとなる。実在するサンプルではあるが、市場の歴史における一つの局面にすぎない。
極端な数値は相場の安値に集中するのか?
下落した月に集中する。ただし、それは別の主張である。2022年以降の各月を、その月の中でトラッカーがどう動いたかによって分類し、各グループに入ったプット/コール指標の上位十分位の数を集計する。
各数値の背後にある正確なSQL
WITH raw AS (
SELECT date AS day,
sumIf(volume, upper(substring(ticker, length(ticker) - 8, 1)) = 'P') AS put_volume,
sumIf(volume, upper(substring(ticker, length(ticker) - 8, 1)) = 'C') AS call_volume
FROM global_markets.options_greeks
WHERE date >= toDate('2022-01-01')
AND date <= toDate('2026-07-31')
AND volume > 0
AND underlying_symbol IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'META',
'TSLA', 'GOOGL', 'JPM', 'KO', 'XOM')
GROUP BY day
HAVING call_volume > 0
),
equity_pcr AS (
SELECT day, toFloat64(put_volume) / toFloat64(call_volume) AS pcr
FROM raw
),
cut AS (
SELECT quantileDeterministic(0.90)(pcr, cityHash64(day)) AS p90
FROM equity_pcr
),
by_month AS (
SELECT toStartOfMonth(day) AS month_start,
countIf(pcr >= cut.p90) AS extreme_reads,
quantileDeterministic(0.5)(pcr, cityHash64(day)) AS median_pcr
FROM equity_pcr CROSS JOIN cut
GROUP BY month_start
),
spy_daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS day,
toFloat64(argMax(close, window_start)) AS close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2022-01-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY day
),
spy_month AS (
SELECT toStartOfMonth(day) AS month_start,
100 * (argMax(close, day) / argMin(close, day) - 1) AS move_pct
FROM spy_daily
GROUP BY month_start
)
SELECT multiIf(s.move_pct <= -3, 'index down 3% or more',
s.move_pct < 0, 'index down under 3%',
s.move_pct < 3, 'index up under 3%',
'index up 3% or more') AS index_move_bucket,
count() AS observations,
round(avg(m.extreme_reads), 1) AS top_decile_reads_avg,
round(quantileDeterministic(0.5)(m.median_pcr, cityHash64(m.month_start)), 2) AS typical_pcr_ratio
FROM by_month AS m
INNER JOIN spy_month AS s ON m.month_start = s.month_start
GROUP BY index_move_bucket
ORDER BY min(s.move_pct) ASCトラッカーが3%以上下落して終えた月では、上位十分位の数が一月当たり平均4.2件だった。これに対し、3%以上上昇した月では1.9件だった。各グループの一日ごとの数値の中央値は最後の列に示しており、最も悪いグループでは0.75、最も良いグループでは0.62である。表の両端には、それぞれ12カ月と22カ月が含まれる。
極端なプット/コール指標と価格下落は同時に現れる。これは同時発生であり、その意味を評価するうえでは前節の先行データが重要になる。この比率は同じ日の相場を測る同日指標であるため、急上昇するのは下落に先行する局面ではなく、下落の最中である。安値というラベルが付くのは、その後である。
分布に照らして水準を読む
上記の数値から、二つの習慣が導かれます。
第一に、比較対象をそろえることです。数値は、同じ指標の過去の推移を、比較可能な期間で見た場合にのみ意味を持ちます。これを示すのがパーセンタイル表であり、記憶に頼った基準値ではありません。
第二に、分母を確認することです。プットの買いが変わらなくても、コールの出来高が急増すれば比率は低下します。比率の低下も急上昇も、分数の片側だけが動いて起こり得ます。そのため、プット出来高とコール出来高を分けて確認すると、計算の動きが明確になります。
この原則は、単独の数値で示されるあらゆるセンチメント指標に当てはまります。VIXも30%のインプライド・ボラティリティの出来高も、それぞれの分布がなければ読み取れません。また、逆張り型のセンチメント・ルールがデータ上で機能するのは、参照水準が推測ではなく測定されている場合に限られます。
よくある質問
put/callレシオが高いと強気材料ですか?
逆張りの見方では、プットの大量購入は、市場参加者がすでに下落を見込んでポジションを取っていることを示します。上記の単一株式バスケットを基準にすると、数値が上位五分の一に入ったセッション後のS&P 500連動商品は、20セッション後の変化率の中央値が3%でした。最も落ち着いた五分の一の後は0.91%でした。上位五分の一の結果の中央五十%は、-1.82%から5.71%の範囲に分布しました。
通常のput/callレシオはどの程度ですか?
何のオプションを集計するかによって、数値は大きく異なります。代表的な単一株式銘柄十銘柄のバスケットでは、2022年から2026年7月までの通常のセッションにおける中央値は、コール一枚当たりプット0.67枚でした。同じ期間の広範な市場ETF三本では、中央値は1.45でした。
なぜ指数のput/callレシオは株式のput/callレシオより高いのですか?
広範な指数やETFのオプションは、ポートフォリオのヘッジに一般的に使われます。ヘッジャーが指数プットを購入しても、それに対応するコール取引が同時に発生するとは限りません。一方、単一株式では、上昇を狙ったコールの購入や、すでに保有する株式に対するコールの売却が多く、レシオは低くなります。
put/callレシオはマーケットタイミングに使えますか?
上記の計測結果は、数値が各五分位に入った後の結果の分布を示しています。どの区分でも、その内部のばらつきは区分間の中央値の差を大きく上回ります。上位十分位の数値は、指数が下落して終えた月にも集中しており、最も悪いグループでは月当たり4.2でした。
出来高put/callレシオと建玉put/callレシオの違いは何ですか?
出来高レシオは、セッション中に取引された契約数を集計するため、毎日リセットされ、素早く変化します。建玉レシオは、未決済のポジションを集計するため、変化は緩やかで、独自の水準で推移します。両者は互換性がありません。一方のレシオから得た閾値をもう一方に適用すると、誤った判断につながります。
これらの数値の算出方法
- 出所は、セッションごとに各オプション契約を一行で記録し、そのセッションの取引出来高を持たせたデータです。プットとコールはOCCの契約コードから区別しています。末尾八文字が行使価格で、その直前の文字がコールを示すC、プットを示すPです。正確なテーブルとフィルターは、各パネルのSQLを開くと確認できます。
- このページのすべてのレシオは出来高レシオです。建玉は計算に含めていないため、ここに建玉レシオはありません。
- インプライド・ボラティリティの品質フィルターは適用していません。これらのパネルはボラティリティではなく取引活動を集計するため、契約は取引出来高だけで取り込んでいます。
- バスケットは、単一株式ではAAPL、MSFT、NVDA、AMZN、META、TSLA、GOOGL、JPM、KO、XOM、指数ETFではSPY、QQQ、IWMです。取引所が公表するレシオは市場全体を対象とし、SPXなどの指数商品も含むため、水準は異なります。
- 指数価格は、S&P 500連動商品の各日の通常取引セッションにおける最後の約定値です。20セッション先のリターンを算出するため、まだ20セッション先のデータがないサンプル末尾の20セッションは除外しています。月次の変化率は、各月の最初のセッションの終値から最後のセッションの終値までで算出しています。
上記の各パネルを展開すると、その裏付けとなるSQLを確認できます。同じパーセンタイル・クエリを、Strasmoreターミナルで追跡している任意の原資産に適用できます。