Skip to main content

CBOE US Option Data Analysis

Put-Call Ratio, Implied Volatility, Max Pain / Wall

Data
Author

gitSAM

Published

October 10, 2026

1 US Equity Options

1.1 옵션의 기본 정의와 권리 구조

미국 주식 옵션은 특정 주식(기초자산, Underlying Asset)을 미래의 지정된 일자(만기일, Expiration Date)까지 미리 정해진 가격(행사가격, Strike Price)으로 사거나 팔 수 있는 권리를 부여하는 표준화된 파생상품 계약이다. 1계약은 일반적으로 기초자산 100주를 인수도하는 권리를 나타낸다.

  • 콜옵션 (Call Option):
    • 매수자(Buyer): 행사가격에 주식을 살 수 있는 권리를 보유하며 프리미엄을 지불한다. 주가 상승 시 수익이 발생한다.
    • 매도자(Seller/Writer): 매수자가 권리를 행사할 때 행사가격에 주식을 넘겨줄 의무를 부담하며 프리미엄을 수취한다.
  • 풋옵션 (Put Option):
    • 매수자(Buyer): 행사가격에 주식을 팔 수 있는 권리를 보유하며 프리미엄을 지불한다. 주가 하락 시 수익이 발생한다.
    • 매도자(Seller/Writer): 매수자가 권리를 행사할 때 행사가격에 주식을 인수할 의무를 부담하며 프리미엄을 수취한다.

1.2 만기 손익 상태(Moneyness)와 가치 소멸 원리

현물 주가(\(S\))와 행사가격(\(K\))의 상대적 위치에 따라 옵션 상태는 세 가지로 구분된다.

  1. 내가격 (ITM, In-The-Money):
    • 콜옵션: \(S > K\) (현재 주가가 행사가격보다 높아 즉시 매수 시 이익 상태)
    • 풋옵션: \(S < K\) (현재 주가가 행사가격보다 낮아 즉시 매도 시 이익 상태)
    • 내재가치(Intrinsic Value)가 존재하는 상태다.
  2. 등가격 (ATM, At-The-Money):
    • \(S \approx K\) (현재 주가와 행사가격이 일치하는 상태)
  3. 외가격 (OTM, Out-Of-The-Money):
    • 콜옵션: \(S < K\) (시장 현물 가격이 행사가보다 저렴하여 옵션을 행사할 유인이 없는 상태)
    • 풋옵션: \(S > K\) (시장 현물 가격이 행사가보다 비싸서 옵션을 행사할 유인이 없는 상태)
    • 내재가치가 0원이며, 시간가치(Time Value)만 존재한다. 만기 도래 시 권리가 행사되지 않고 완전히 소멸하여 가치가 0원(Worthless)이 된다.

1.3 옵션 티커 표준 명명 규격 (OSI 규격)

CBOE를 비롯한 미국 옵션 거래소는 미국 옵션 심볼 규격(OSI, Option Symbology Initiative)에 따라 계약 코드를 표기한다.

  • 예시 티커: NVDA261009C00050000
    • 루트 심볼 (Root Symbol): NVDA (기초자산 티커)
    • 만기 연도 (YY): 26 (2026년)
    • 만기 월 (MM): 10 (10월)
    • 만기 일 (DD): 09 (09일)
    • 옵션 유형 (Type): C (Call) 또는 P (Put)
    • 행사가격 (Strike): 00050000 (소수점 3자리 고정 표기로 $50.00 달러를 의미)

1.4 거래량(Volume)과 미결제약정(Open Interest)의 구분

옵션 시장을 분석할 때 거래량과 미결제약정은 서로 다른 성격의 정보를 제공한다.

  • 거래량 (Volume):
    • 당일 하루 동안 체결된 옵션 계약의 총수.
    • 당일 시장 참여자들의 즉각적인 거래 활성도와 단기 뉴스 반응도를 대변한다. 하루가 지나면 0으로 리셋된다.
  • 미결제약정 (Open Interest, OI):
    • 거래가 체결된 후 청산(매도/환매수)되거나 권리행사/소멸되지 않고 시장에 유지되고 있는 총 유효 계약 잔고.
    • 기관 및 투자자들이 실제로 자금을 묶어두고 유지 중인 포지션의 누적 규모를 보여주며, 중장기 지지선 및 저항선 분석의 핵심 척도 역할을 한다.

2 CBOE 옵션 시장 심리 지표와 구조적 가격선 이론

2.1 풋콜비율 (Put-Call Ratio, PCR)

풋콜비율은 풋옵션의 수량을 콜옵션의 수량으로 나눈 지표로, 시장 참여자들의 강세/약세 심리를 판별하는 대표적인 센티먼트 지표다.

\[\text{PCR} = \frac{\text{Put 수량}}{\text{Call 수량}}\]

  • \(\text{PCR} < 1.0\): 콜옵션 거래가 풋옵션보다 많음을 의미하며, 시장의 상승 기대(강세 심리)가 우세함을 반영한다.
  • \(\text{PCR} > 1.0\): 풋옵션 거래가 콜옵션보다 많음을 의미하며, 하방 위험에 대한 헤지 수요나 약세 베팅이 우세함을 가리킨다.
  • 거래량 기준 PCR(Volume PCR)은 당일의 즉각적인 쏠림을 측정하고, 미결제약정 기준 PCR(OI PCR)은 누적된 구조적 포지셔닝을 평가한다.

2.2 30일 내재변동성 (IV30)과 시장심리 사분면 매트릭스

내재변동성(Implied Volatility, IV)은 블랙-숄즈(Black-Scholes) 옵션 가격 모델 등에서 시장에 형성된 실제 옵션 프리미엄을 기반으로 역산한 연율화 기대 변동폭이다. CBOE가 산출하는 IV30은 향후 30일간 기초자산의 기대 변동성을 나타낸다.

IV30과 PCR을 2차원 축으로 결합하면 시장의 국면을 4개 사분면으로 분류할 수 있다.

  1. 높은 IV + 낮은 PCR (제2사분면):
    • 콜옵션에 공격적인 투기 매수세가 유입되면서 변동성 프리미엄이 급등한 상태. 단기 과열 및 가격 버블 위험을 시사한다.
  2. 높은 IV + 높은 PCR (제1사분면):
    • 주가 급락 공포로 인해 하방 풋옵션 헤지 수요가 폭발한 패닉 국면.
  3. 낮은 IV + 낮은 PCR (제3사분면):
    • 변동성이 억제된 상태에서 꾸준한 콜옵션 매수가 동반되는 안정적 강세장 국면.
  4. 낮은 IV + 높은 PCR (제4사분면):
    • 시장 참여자들이 큰 변동성을 예상하지 않으면서 방어적으로 풋옵션을 보유하는 조용한 횡보/헤지 국면.

2.3 딜러 포지셔닝과 구조적 가격선: Call Wall, Put Wall, Max Pain

옵션 시장의 유동성을 공급하는 마켓 메이커(딜러)는 옵션을 매도하고 기초자산 현물 주식을 매매하여 델타를 0으로 유지하는 델타 헤징(Delta Hedging)을 수행한다. 이 메커니즘으로 인해 대규모 미결제약정이 형성된 행사가격은 강력한 가격 방어선으로 작용한다.

  • 콜 벽 (Call Wall):
    • 전체 행사가격 중 콜옵션 미결제약정이 가장 많이 집중된 가격대.
    • 주가가 이 지점에 도달하면 콜옵션을 매도한 딜러들의 매도 압력이 커지며 강력한 상방 저항선으로 작동한다.
  • 풋 벽 (Put Wall):
    • 전체 행사가격 중 풋옵션 미결제약정이 가장 많이 집중된 가격대.
    • 주가가 이 지점 밑으로 떨어질 경우 풋옵션 매도 포지션의 손실이 급증하므로, 하방 붕괴를 저지하는 강력한 지지선 역할을 수행한다.
  • 최대 고통점 (Max Pain):
    • 만기일에 옵션 매수자들의 총 내재가치 합산이 최소화되어, 대다수 옵션이 무가치(OTM)로 소멸하는 가격대.
    • 마켓 메이커가 프리미엄을 최대로 취득할 수 있는 지점이며, 만기일이 다가올수록 주가가 이 가격대로 수렴(Pinning)하려는 경향을 보인다.

\[\text{Total Loss}(S) = \sum_{k} \left[ \text{Call\_OI}_k \times \max(0, S - K_k) + \text{Put\_OI}_k \times \max(0, K_k - S) \right]\]

위 식에서 총 지급 손실액 \(\text{Total Loss}(S)\)를 최소화하는 행사가격 \(S\)를 구하면 Max Pain 가격이 도출된다.


3 CBOE 데이터 수집 및 해석

CBOE는 공식 CDN 엔드포인트를 통해 지연 시세 기반의 전 종목 옵션 체인을 JSON 포맷으로 공개 제공한다.

  • 엔드포인트 URL: https://cdn.cboe.com/api/global/delayed_quotes/options/{SYMBOL}.json
  • 지원 심볼: 개별 주식 티커(NVDA, PLTR 등) 및 인덱스 지표(_SPX, _VIX 등)

필요한 패키지를 임포트하고 시각화 기본 스타일을 설정한다.

Code
import re
import requests
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 시각화 기본 스타일 설정 (영문 기본 폰트)
plt.style.use("seaborn-v0_8-whitegrid" if "seaborn-v0_8-whitegrid" in plt.style.available else "default")
plt.rcParams["axes.unicode_minus"] = False

print("Required analytics libraries loaded successfully.")
Required analytics libraries loaded successfully.

CBOE 엔드포인트 호출, 옵션 티커 정규식 파싱, Max Pain 및 지지·저항벽 연산 함수를 정의한다.

Code
CBOE_HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}

def fetch_cboe_options(symbol: str) -> dict:
    """CBOE CDN 지연 시세 API로부터 특정 심볼의 전체 옵션 체인 JSON 수신"""
    url = f"https://cdn.cboe.com/api/global/delayed_quotes/options/{symbol}.json"
    resp = requests.get(url, headers=CBOE_HEADERS, timeout=15)
    resp.raise_for_status()
    return resp.json()

def parse_option_symbol(opt_symbol: str):
    """OSI 옵션 심볼 규격 파싱 (만기일, Call/Put, Strike 도출)"""
    match = re.match(r"^([A-Z_]+)(\d{2})(\d{2})(\d{2})([CP])(\d{8})$", opt_symbol)
    if not match:
        return None, None, None, None
    base_sym, yy, mm, dd, opt_type, strike_str = match.groups()
    exp_date = f"20{yy}-{mm}-{dd}"
    strike = int(strike_str) / 1000.0
    return exp_date, opt_type, strike

def calculate_max_pain(pivot_oi: pd.DataFrame) -> float:
    """행사가격별 총 옵션 매수자 내재가치를 계산하여 최소 손실 행사가 산출"""
    strikes = pivot_oi.index.values
    call_oi = pivot_oi["CALL"].values
    put_oi = pivot_oi["PUT"].values
    
    total_losses = []
    for s in strikes:
        call_loss = np.sum(np.maximum(0, s - strikes) * call_oi)
        put_loss = np.sum(np.maximum(0, strikes - s) * put_oi)
        total_losses.append(call_loss + put_loss)
        
    return strikes[np.argmin(total_losses)]

def analyze_cboe_options(symbol: str):
    """단일 심볼에 대한 옵션 체인 정제, 주요 PCR 및 구조 레벨 산출 총괄"""
    raw = fetch_cboe_options(symbol)
    d = raw.get("data", {})
    
    current_price = d.get("current_price", 0.0)
    prev_close = d.get("prev_day_close", 0.0)
    iv30 = d.get("iv30", 0.0)
    raw_options = d.get("options", [])
    
    parsed_rows = []
    for opt in raw_options:
        opt_sym = opt.get("option", "")
        exp_date, opt_type, strike = parse_option_symbol(opt_sym)
        if not opt_type:
            continue
            
        vol = float(opt.get("volume", 0.0) or 0.0)
        oi = float(opt.get("open_interest", 0.0) or 0.0)
        iv = float(opt.get("iv", 0.0) or 0.0)
        
        parsed_rows.append({
            "symbol": symbol,
            "option": opt_sym,
            "expiration": exp_date,
            "type": "CALL" if opt_type == "C" else "PUT",
            "strike": strike,
            "volume": vol,
            "open_interest": oi,
            "iv": iv
        })
        
    df_opts = pd.DataFrame(parsed_rows)
    
    call_vol = df_opts[df_opts["type"] == "CALL"]["volume"].sum()
    put_vol = df_opts[df_opts["type"] == "PUT"]["volume"].sum()
    call_oi = df_opts[df_opts["type"] == "CALL"]["open_interest"].sum()
    put_oi = df_opts[df_opts["type"] == "PUT"]["open_interest"].sum()
    
    pcr_vol = (put_vol / call_vol) if call_vol > 0 else np.nan
    pcr_oi = (put_oi / call_oi) if call_oi > 0 else np.nan
    
    # 행사가격별 미결제약정 피벗
    pivot_oi = df_opts.groupby(["strike", "type"])["open_interest"].sum().unstack(fill_value=0)
    if "CALL" not in pivot_oi: pivot_oi["CALL"] = 0
    if "PUT" not in pivot_oi: pivot_oi["PUT"] = 0
    
    call_wall = pivot_oi["CALL"].idxmax() if len(pivot_oi) > 0 else np.nan
    put_wall = pivot_oi["PUT"].idxmax() if len(pivot_oi) > 0 else np.nan
    max_pain = calculate_max_pain(pivot_oi) if len(pivot_oi) > 0 else np.nan
    
    summary = {
        "Symbol": symbol,
        "Price": current_price,
        "IV30": iv30,
        "Put Wall": put_wall,
        "Max Pain": max_pain,
        "Call Wall": call_wall,
        "PCR (Volume)": round(pcr_vol, 4),
        "PCR (OI)": round(pcr_oi, 4),
        "Call Volume": int(call_vol),
        "Put Volume": int(put_vol),
        "Call OI": int(call_oi),
        "Put OI": int(put_oi),
        "Total Contracts": len(df_opts)
    }
    
    return summary, df_opts, pivot_oi

print("Option analytics engine defined successfully.")
Option analytics engine defined successfully.

시장 벤치마크 지수 2종(_SPX, _VIX)과 미국 테크 대표 5개 종목(PLTR, MSFT, NVDA, AMD, DELL)을 대상으로 실제 데이터를 조회하여 종합 데이터프레임을 생성한다.

Code
target_symbols = ["_SPX", "_VIX", "PLTR", "MSFT", "NVDA", "AMD", "DELL"]

summaries = []
options_data_map = {}
pivots_map = {}

for sym in target_symbols:
    try:
        summary, df_opts, pivot_oi = analyze_cboe_options(sym)
        summaries.append(summary)
        options_data_map[sym] = df_opts
        pivots_map[sym] = pivot_oi
    except Exception as e:
        print(f"[{sym}] Data fetch error: {e}")

df_summary = pd.DataFrame(summaries)
display_cols = ["Symbol", "Price", "Put Wall", "Max Pain", "Call Wall", "PCR (Volume)", "PCR (OI)", "IV30", "Total Contracts"]
df_summary[display_cols]
Symbol Price Put Wall Max Pain Call Wall PCR (Volume) PCR (OI) IV30 Total Contracts
0 _SPX 7811.5400 7000.0 7500.0 7000.0 1.2375 1.4367 11.649 29904
1 _VIX 14.8400 17.0 19.0 20.0 0.4368 0.3303 86.658 1520
2 PLTR 208.7300 140.0 150.0 200.0 0.6082 1.0506 56.571 2494
3 MSFT 535.0000 350.0 460.0 575.0 0.6459 0.5775 31.293 3872
4 NVDA 229.3300 200.0 200.0 200.0 0.7591 0.9064 29.642 4410
5 AMD 608.4943 300.0 440.0 1120.0 0.7833 1.1341 53.697 7314
6 DELL 586.1000 400.0 450.0 600.0 0.9823 1.3675 56.426 3934

3.1 결과 수치 해석

  1. 시장 벤치마크 (_SPX, _VIX):
    • _SPX의 거래량 PCR은 1.2375, 미결제약정 PCR은 1.8415로 나타난다. 기관 포트폴리오의 하방 꼬리위험(Tail Risk) 헤지용 풋옵션 매수가 누적되어 상시 1.0을 크게 웃도는 전형적인 지수 옵션 구조를 보인다.
    • _VIX는 변동성 지수 옵션으로, 지수 하락 시 VIX가 급등하므로 콜옵션이 시장 하방 헤지 역할을 수행한다. 이에 따라 PCR(Volume)은 0.4368로 낮은 수치를 나타낸다.
  2. 개별 주식 (PLTR, MSFT, NVDA, AMD, DELL):
    • PLTR의 PCR(Volume)은 0.6082, MSFT는 0.6459, NVDA는 0.7591로 대형 기술주 전반에서 콜옵션 매수세가 풋옵션을 압도하고 있다.
    • NVDA의 경우 Put Wall, Max Pain, Call Wall이 모두 $200.0 달러 선에 형성되어 있어, 해당 가격대에 막대한 옵션 만기 계약이 결집되어 있음을 증명한다.

4 시각화 및 시장 심리 정량 분석

4.1 시각화 1: 종목별 Volume PCR vs Open Interest PCR 비교

당일 거래량 기준 PCR(당일 단기 심리)과 미결제약정 기준 PCR(누적 포지션 심리)을 중립선(1.0)과 함께 비교한다.

Code
fig, ax = plt.subplots(figsize=(11, 5.5))

x = np.arange(len(df_summary))
width = 0.35

bars1 = ax.bar(x - width/2, df_summary["PCR (Volume)"], width, label="PCR (Volume)", color="#2b5c8f", alpha=0.9)
bars2 = ax.bar(x + width/2, df_summary["PCR (OI)"], width, label="PCR (Open Interest)", color="#d95f02", alpha=0.9)

ax.axhline(1.0, color="red", linestyle="--", linewidth=1.5, label="Neutral Line (PCR = 1.0)")

ax.set_title("CBOE Option Market: Put-Call Ratio by Symbol (Volume vs. Open Interest)", fontsize=13, pad=12)
ax.set_ylabel("Put-Call Ratio (Put / Call)", fontsize=11)
ax.set_xticks(x)
ax.set_xticklabels(df_summary["Symbol"], fontsize=11)
ax.legend(frameon=True, facecolor="white", loc="upper right")
ax.grid(True, linestyle=":", alpha=0.6)

for bar in bars1:
    h = bar.get_height()
    if not np.isnan(h):
        ax.annotate(f"{h:.2f}", xy=(bar.get_x() + bar.get_width()/2, h), xytext=(0, 3),
                    textcoords="offset points", ha="center", va="bottom", fontsize=9)

for bar in bars2:
    h = bar.get_height()
    if not np.isnan(h):
        ax.annotate(f"{h:.2f}", xy=(bar.get_x() + bar.get_width()/2, h), xytext=(0, 3),
                    textcoords="offset points", ha="center", va="bottom", fontsize=9)

plt.tight_layout()
plt.show()

4.2 시각화 2: 30일 내재변동성(IV30) vs Put-Call Ratio (시장 심리 매트릭스)

종목별 PCR과 IV30을 교차하여 콜옵션 과열(투기), 안정 상승, 하방 헤지 공포 국면을 구분한다.

Code
fig, ax = plt.subplots(figsize=(9, 6.5))

for idx, row in df_summary.iterrows():
    sym = row["Symbol"]
    pcr = row["PCR (Volume)"]
    iv = row["IV30"]
    if np.isnan(pcr) or np.isnan(iv):
        continue
    is_index = sym.startswith("_")
    color = "#e41a1c" if is_index else "#377eb8"
    size = 280 if is_index else 200
    
    ax.scatter(pcr, iv, s=size, color=color, alpha=0.85, edgecolors="black", linewidth=1.2, zorder=5)
    ax.annotate(f"{sym}\n(${row['Price']:.1f})", xy=(pcr, iv), xytext=(8, -5),
                textcoords="offset points", fontsize=10, zorder=6)

ax.axvline(1.0, color="gray", linestyle="--", alpha=0.7)
ax.axhline(df_summary["IV30"].median(), color="gray", linestyle="--", alpha=0.7)

ax.set_title("CBOE Market Sentiment Matrix: Put-Call Ratio vs. 30-Day Implied Volatility (IV30)", fontsize=13, pad=12)
ax.set_xlabel("Put-Call Ratio (Volume)", fontsize=11)
ax.set_ylabel("30-Day Implied Volatility (IV30, %)", fontsize=11)
ax.grid(True, linestyle=":", alpha=0.6)

plt.tight_layout()
plt.show()

4.3 시각화 3: 행사가격(Strike)별 Open Interest 분포와 핵심 구조선

관심 5개 종목(PLTR, MSFT, NVDA, AMD, DELL)의 행사가격별 Call과 Put 미결제약정 분포 막대 위에 현재 주가, Max Pain, Put Wall, Call Wall을 수직선으로 오버레이한다.

Code
stocks = ["PLTR", "MSFT", "NVDA", "AMD", "DELL"]
fig, axes = plt.subplots(len(stocks), 1, figsize=(13, 19), sharex=False)

for i, sym in enumerate(stocks):
    ax = axes[i]
    if sym not in pivots_map or sym not in options_data_map:
        continue
        
    pivot_oi = pivots_map[sym]
    summary_row = df_summary.loc[df_summary["Symbol"] == sym].iloc[0]
    
    cur_price = summary_row["Price"]
    put_wall = summary_row["Put Wall"]
    max_pain = summary_row["Max Pain"]
    call_wall = summary_row["Call Wall"]
    
    # 핵심선들을 모두 포함하는 표시 범위 필터링
    min_focus = min(cur_price, put_wall, max_pain) * 0.85
    max_focus = max(cur_price, call_wall, max_pain) * 1.15
    
    pivot_filtered = pivot_oi[(pivot_oi.index >= min_focus) & (pivot_oi.index <= max_focus)]
    strikes = pivot_filtered.index.values
    call_oi = pivot_filtered["CALL"].values
    put_oi = pivot_filtered["PUT"].values
    
    width = (strikes[1] - strikes[0]) * 0.4 if len(strikes) > 1 else 1.0
    
    # Call / Put 막대
    ax.bar(strikes - width/2, call_oi, width=width, label="Call Open Interest", color="#2ca02c", alpha=0.75)
    ax.bar(strikes + width/2, put_oi, width=width, label="Put Open Interest", color="#d62728", alpha=0.75)
    
    # 4 core benchmark lines
    ax.axvline(cur_price, color="black", linestyle="-", linewidth=2.2, label=f"Current Price: ${cur_price:.2f}", zorder=10)
    ax.axvline(max_pain, color="#9467bd", linestyle="--", linewidth=2.0, label=f"Max Pain: ${max_pain:.1f}", zorder=9)
    ax.axvline(put_wall, color="#d62728", linestyle=":", linewidth=2.5, label=f"Put Wall (Support): ${put_wall:.1f}", zorder=8)
    ax.axvline(call_wall, color="#1f77b4", linestyle=":", linewidth=2.5, label=f"Call Wall (Resistance): ${call_wall:.1f}", zorder=8)
    
    ax.set_title(f"{sym} Options Open Interest by Strike Price (Current: ${cur_price:.2f} | Max Pain: ${max_pain:.1f})", 
                 fontsize=12, pad=10)
    ax.set_xlabel("Strike Price ($)", fontsize=10)
    ax.set_ylabel("Open Interest (Contracts)", fontsize=10)
    ax.legend(loc="upper right", frameon=True, facecolor="white", framealpha=0.9, fontsize=9)
    ax.grid(True, linestyle=":", alpha=0.6)

plt.tight_layout()
plt.show()


5 실전 적용 시사점

  1. 단기 모멘텀과 누적 포지션의 괴리 추적:
    • Volume PCR이 1.0 미만으로 떨어지며 단기 콜옵션 과열이 발생하더라도, Open Interest 기준 Call Wall에 근접했을 때는 딜러들의 헤징 매도 압력으로 주가 상승 탄력이 둔화될 가능성을 경계해야 한다.
  2. Max Pain을 활용한 만기주 핀 수렴 전략:
    • 월물/주간 만기일(금요일 장마감)이 임박할수록 옵션 발행자들의 수익 극대화 심리로 인해 현물 주가가 Max Pain 지점으로 강하게 회귀하려는 성향이 나타난다.
  3. CBOE 공식 공개 데이터의 비용 효율적 활용:
    • CBOE CDN 지연 엔드포인트를 활용하면 고가의 유료 데이터 피드 없이도 옵션 체인 전체의 볼륨과 미결제약정을 무료로 안정적으로 파싱하여 매크로 및 개별 종목의 심리 지표를 자체 구축할 수 있다.