Czy wysoki wskaźnik put/call jest byczy?
Kontrarianie uznają wysoki wskaźnik put/call za sygnał wzrostowy. Sprawdź przedziały percentylowe opcji akcyjnych i indeksowych oraz skutki skrajnych odczytów.
Wysoki wskaźnik put/call to klasyczny kontrariański sygnał wzrostowy: wyjątkowo intensywny zakup opcji put uznaje się za oznakę, że większość inwestorów jest już przygotowana na spadki. Wykorzystanie tego sygnału napotyka jednak jeden problem. „Wysoki” nie ma ustalonej wartości. Odczyt 1,15 na ekranie może oznaczać skrajny poziom w przypadku opcji na pojedyncze akcje, ale zwyczajną sesję na produktach indeksowych.
Do właściwej oceny potrzebny jest rozkład referencyjny. Na tej stronie przedstawiono go dla obu grup, a następnie zmierzono, co działo się po odczytach na wysokich poziomach. Objaśnienie wskaźnika put/call opisuje sposób jego konstrukcji. Wszystkie poniższe dane opierają się na tej definicji.
Dwie uwagi dotyczące pomiaru. Każdy wskaźnik uwzględnia liczbę kontraktów zawartych danego dnia, dlatego jest wskaźnikiem wolumenu. Liczba otwartych pozycji obejmuje nadal aktywne pozycje i odnosi się do innej kategorii danych (wolumen a liczba otwartych pozycji wyjaśnia różnicę). Dane pochodzą również ze stałego koszyka: obejmują dziesięć popularnych spółek oraz trzy ETF-y szerokiego rynku, a nie cały rynek. Należy zatem analizować kształt rozkładu, a nie przywiązywać nadmiernej wagi do ostatniego miejsca po przecinku.
Jaki poziom wskaźnika put/call uznaje się za wysoki?
Percentyl odpowiada na pytanie, na które pojedynczy poziom nie daje odpowiedzi. Poniższa krzywa obejmuje każdą sesję od stycznia 2022 roku do lipca 2026 roku. Dla każdego portfela przypada jeden wskaźnik na sesję.
Dokładny kod SQL dla każdej liczby
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
)W koszyku pojedynczych akcji mediana sesji wyniosła 0.67 opcji put na jedną opcję call. Najwyższy decyl sesji zaczynał się od 0.89, a najbardziej ekstremalny jeden procent przekraczał 1.34. Spokojniejszy kraniec rozkładu jest równie przydatny do kalibracji: jedna sesja na dwadzieścia kończyła się na poziomie 0.48 lub niższym.
Kolumna ETF przedstawia na każdym poziomie krzywej inny rozkład. Mediana sesji wyniosła 1.45, czyli powyżej relacji one-to-one, względem której mediana pojedynczych akcji znajduje się wyraźnie niżej. Własny najwyższy decyl zaczynał się natomiast od 1.77. Wskaźnik podany bez wskazania portfela jest niemal pozbawiony znaczenia. Wartość 1,15 oznacza dwie różne rzeczy, zależnie od tego, z której kolumny pochodzi.
Dlaczego wskaźnik dla indeksu powyżej 1 jest zjawiskiem normalnym, a wskaźnik dla akcji powyżej 1 — nie
Podział tego samego wolumenu według instrumentu bazowego wyraźnie rozdziela oba poziomy.
Dokładny kod SQL dla każdej liczby
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 DESCW ciągu pierwszych siedmiu miesięcy 2026 roku IWM zajmował czołowe miejsce w zestawieniu, z wynikiem 2.73 opcji put na jedną opcję call. W 98.6% z 144 sesji wskaźnik przekraczał 1. Na drugim końcu zestawienia XOM osiągnął poziom 0.38, a wartość powyżej 1 odnotowano podczas 2.8% sesji.
Różnica ma charakter strukturalny. Opcje na ETF-y szerokiego rynku służą do zabezpieczania portfeli. Zarządzający posiadający dwieście pozycji kupuje opcje put na indeks zamiast nabywać opcje put na każdą spółkę. Taki przepływ nie ma odpowiadającej mu transakcji na opcjach call. Wolumen opcji na pojedyncze akcje ma odwrotną strukturę. Dominuje w nim zakup opcji call w celu uzyskania ekspozycji na wzrost oraz wystawianie opcji call na posiadane akcje. Wskaźnik „łączny” łączy oba segmenty. Dlatego plasuje się pomiędzy nimi i zależy od struktury instrumentów notowanych danego dnia w podobnym stopniu jak od nastrojów rynkowych.
Warto znać jeszcze jedną przyczynę przesunięcia poziomów. Obecnie znaczna część wolumenu indeksów i ETF-ów przypada na opcje wygasające tego samego dnia (opcje 0DTE). Gdy formułowano znane progi, ta kategoria nie była przedmiotem obrotu na porównywalną skalę. Dawne poziomy nie mogą być bezpośrednio przenoszone na rynek o innym składzie.
Czy wysoki wskaźnik put/call jest sygnałem wzrostowym? Co następowało po skrajnych odczytach
Tezę kontrariańską można zweryfikować. Każdą sesję uporządkowano według wartości wskaźnika dla akcji i podzielono na pięć grup, a następnie zmierzono zmianę indeksu S&P 500 w ciągu kolejnych 5 i 20 sesji.
Dokładny kod SQL dla każdej liczby
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 ASCNajspokojniejsza grupa sesji zaczyna się od 0.34, a najbardziej aktywna od 0.81, dlatego najwyższy przedział obejmuje wszystkie odczyty, które inwestor kontrariański uznałby za skrajne. W przypadku tych 226 sesji mediana zmiany w perspektywie 20 sesji wyniosła 3%, wobec 0.91% po najspokojniejszej grupie. Po pięciu sesjach te same dwa przedziały wskazywały odpowiednio 0.82% i 0.3%.
Mediany nie pokazują jednak najważniejszego elementu. W najwyższej grupie środkowa połowa wyników w perspektywie 20 sesji mieściła się między -1.82% a 5.71%. W najspokojniejszej grupie środkowa połowa obejmowała przedział od -0.83% do 2.67%. Zakresy te w dużej mierze się pokrywają. Przedział, do którego trafia dana sesja, przesuwa środek rozkładu, ale tylko nieznacznie zawęża zakres wokół tego środka. Tego elementu nie uwzględnia prosta reguła orientacyjna.
Zastrzeżenie dotyczące wagi próby. Okres od stycznia 2022 roku do lipca 2026 roku obejmuje jedną bessę i następujące po niej ożywienie, czyli około 226 sesji w każdej grupie. Jest to rzeczywista próba, ale obejmuje tylko jeden odcinek historii rynku.
Czy skrajne odczyty grupują się przy dołkach rynkowych?
Grupują się w miesiącach spadkowych, co jest innym stwierdzeniem. Każdy miesiąc od 2022 roku przyporządkowano do grupy według zmiany wartości wskaźnika w jego trakcie, a następnie policzono, ile odczytów put/call z najwyższego decyla przypadło na każdą grupę.
Dokładny kod SQL dla każdej liczby
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) ASCW miesiącach, w których wskaźnik zakończył okres spadkiem o co najmniej 3%, przypadało średnio 4.2 odczytów z najwyższego decyla, wobec 1.9 w miesiącach, w których wzrósł o co najmniej 3%. Mediana dziennych odczytów dla każdej grupy znajduje się w ostatniej kolumnie i wynosi 0.75 dla najsłabszej grupy oraz 0.62 dla najlepszej. Na obu krańcach tabeli znajduje się odpowiednio 12 oraz 22 miesięcy.
Skrajne odczyty put/call i spadki cen występują jednocześnie. Jest to współwystępowanie. To właśnie pokazują dane dotyczące przyszłych wyników przedstawione w poprzedniej części. Wskaźnik jest pomiarem jednodniowym opartym na jednodniowym przebiegu notowań, dlatego jego skoki pojawiają się w trakcie spadków, a nie przed nimi. Określenie „dołek” zostaje przypisane dopiero później.
Odczytywanie poziomu na tle rozkładu
Z powyższych danych wynikają dwa praktyczne wnioski.
Po pierwsze, należy porównywać wartości na tej samej podstawie. Odczyt ma znaczenie wyłącznie na tle historii tego samego zestawu danych w porównywalnym okresie. Właśnie to pokazuje tabela percentylowa, czego nie zapewnia zapamiętany próg.
Po drugie, należy obserwować mianownik. Wskaźnik spada, gdy wolumen opcji call gwałtownie rośnie, nawet jeśli zakupy opcji put pozostają bez zmian. Zarówno spadek, jak i wzrost wskaźnika mogą wynikać wyłącznie ze zmiany jednej strony ułamka. Odczytywanie wolumenu opcji put i call oddzielnie pozwala zachować przejrzystość obliczeń.
Ta sama zasada dotyczy każdego wskaźnika nastrojów podawanego jako pojedyncza liczba. VIX i odczyt zmienności implikowanej na poziomie 30% są nieczytelne bez własnych rozkładów, a kontrariańskie reguły oceny nastrojów mają potwierdzenie w danych tylko wtedy, gdy poziom odniesienia jest mierzony, a nie przyjmowany z góry.
Najczęściej zadawane pytania
Czy wysoki wskaźnik put/call jest sygnałem wzrostowym?
Interpretacja kontrariańska zakłada, że intensywne kupowanie opcji put oznacza, iż inwestorzy masowo zajęli już pozycje zakładające spadki. W porównaniu z przedstawionym wyżej koszykiem pojedynczych akcji, po sesjach należących do najwyższej jednej piątej odczytów mediana 20-sesyjnej zmiany na ETF-ie replikującym S&P 500 wyniosła 3%, wobec 0.91% po najspokojniejszej jednej piątej sesji. Środkowa połowa wyników z najwyższej jednej piątej mieściła się w przedziale od -1.82% do 5.71%.
Jaki poziom wskaźnika put/call jest uznawany za normalny?
Zależy to całkowicie od tego, jakie opcje są uwzględniane. W koszyku obejmującym dziesięć popularnych pojedynczych akcji mediana dla sesji od 2022 roku do lipca 2026 roku wyniosła 0.67 opcji put na jedną opcję call. Dla trzech ETF-ów szerokiego rynku w tych samych sesjach mediana wyniosła 1.45.
Dlaczego wskaźnik put/call dla indeksu jest wyższy niż wskaźnik put/call dla akcji?
Opcje na szerokie indeksy i ETF-y są standardowym instrumentem zabezpieczania portfela. Inwestor zabezpieczający pozycję przez zakup opcji put na indeks nie zawiera odpowiadającej jej transakcji na opcjach call. Wolumen obrotu pojedynczymi akcjami jest natomiast w większym stopniu związany z kupowaniem opcji call w oczekiwaniu na wzrost oraz wystawianiem opcji call na posiadane już akcje. Utrzymuje to niższy poziom wskaźnika w tej grupie.
Czy wskaźnik put/call sprawdza się w określaniu momentu wejścia na rynek?
Powyższy pomiar pokazuje rozkład zmian następujących po każdej jednej piątej odczytów. Zmienność wyników wewnątrz każdej grupy jest znacznie większa niż różnica między medianami grup. Odczyty z najwyższego decyla występują również częściej w miesiącach, w których indeks zakończył okres spadkiem. W najgorszej grupie odsetek takich miesięcy wyniósł 4.2.
Jaka jest różnica między wskaźnikiem put/call opartym na wolumenie a wskaźnikiem opartym na open interest?
Wskaźnik oparty na wolumenie obejmuje kontrakty zawarte podczas sesji. Jest więc wyliczany od nowa każdego dnia i szybko reaguje na zmiany. Wskaźnik oparty na open interest obejmuje pozycje pozostające otwarte. Zmienia się wolniej i utrzymuje na własnym poziomie. Tych dwóch miar nie można stosować zamiennie. Próg ustalony dla jednej z nich może prowadzić do błędnej interpretacji drugiej.
Jak obliczane są te wartości
- Źródło: jeden wiersz dla każdego kontraktu opcyjnego w każdej sesji, zawierający wolumen obrotu tego kontraktu podczas danej sesji. Opcje put i call są rozdzielane na podstawie kodu kontraktu OCC. Ostatnie osiem znaków oznacza cenę wykonania, a znak znajdujący się bezpośrednio przed nimi to C dla opcji call albo P dla opcji put. Pod każdym panelem znajduje się kod SQL pokazujący dokładną tabelę i zastosowane filtry.
- Wszystkie wskaźniki na tej stronie są wskaźnikami opartymi na wolumenie. Open interest nie jest uwzględniany w obliczeniach, dlatego żaden z przedstawionych wskaźników nie jest wskaźnikiem opartym na open interest.
- Nie stosuje się filtra jakości zmienności implikowanej. Kontrakty są uwzględniane wyłącznie na podstawie wolumenu obrotu, ponieważ panele mierzą aktywność handlową, a nie zmienność.
- Koszyk obejmuje AAPL, MSFT, NVDA, AMZN, META, TSLA, GOOGL, JPM, KO i XOM w grupie pojedynczych akcji oraz SPY, QQQ i IWM w grupie ETF-ów indeksowych. Wskaźniki publikowane przez giełdy obejmują cały rynek oraz produkty indeksowe, takie jak SPX, dlatego ich poziomy są inne.
- Ceny indeksu odpowiadają ostatnim transakcjom z regularnej sesji każdego dnia dla ETF-u replikującego S&P 500. Przy obliczaniu przyszłych stóp zwrotu pomija się ostatnie 20 sesji próby, ponieważ nie mają jeszcze pełnego 20-sesyjnego okresu przyszłych danych. Zmiany miesięczne są liczone od kursu zamknięcia pierwszej sesji do kursu zamknięcia ostatniej sesji danego miesiąca.
Każdy z powyższych paneli można rozwinąć, aby wyświetlić kod SQL wykorzystany do obliczeń. Te same zapytania percentylowe można zastosować do dowolnego instrumentu obserwowanego w terminalu Strasmore.