옵션 그릭스란? 파생상품 리스크의 핵심
옵션 트레이딩에서 그릭스(Greeks)는 옵션 가격이 기초자산 가격, 시간, 변동성 등의 변화에 얼마나 민감한지를 수치로 표현한 지표입니다. 퀀트 트레이더가 포지션 리스크를 정량적으로 관리하려면 그릭스 계산은 필수입니다.
주요 그릭스 5가지:
- 델타(Δ): 기초자산 가격 변화에 대한 옵션 가격 민감도
- 감마(Γ): 델타의 변화율 — 비선형 리스크 측정
- 세타(Θ): 시간 경과에 따른 옵션 가치 감소(시간가치 소멸)
- 베가(ν): 내재변동성 변화에 대한 가격 민감도
- 로(ρ): 금리 변화에 대한 가격 민감도
이 글에서는 Black-Scholes 모델을 파이썬으로 구현하고, 그릭스를 계산하며, 실전 델타 헤지 전략까지 다룹니다.
Black-Scholes 모델 파이썬 구현
Black-Scholes 공식은 유럽형 옵션의 이론 가격을 계산하는 표준 모델입니다. 파이썬의 scipy를 활용하면 간결하게 구현할 수 있습니다.
import numpy as np
from scipy.stats import norm
class BlackScholes:
"""Black-Scholes 옵션 가격 및 그릭스 계산기"""
def __init__(self, S, K, T, r, sigma, option_type='call'):
"""
S: 기초자산 현재가
K: 행사가
T: 잔존 만기 (연 단위)
r: 무위험 이자율
sigma: 내재변동성
option_type: 'call' 또는 'put'
"""
self.S = S
self.K = K
self.T = T
self.r = r
self.sigma = sigma
self.type = option_type
self._calc_d()
def _calc_d(self):
"""d1, d2 계산"""
self.d1 = (np.log(self.S / self.K)
+ (self.r + 0.5 * self.sigma**2) * self.T)
/ (self.sigma * np.sqrt(self.T))
self.d2 = self.d1 - self.sigma * np.sqrt(self.T)
def price(self):
"""옵션 이론가 계산"""
if self.type == 'call':
return (self.S * norm.cdf(self.d1)
- self.K * np.exp(-self.r * self.T) * norm.cdf(self.d2))
else:
return (self.K * np.exp(-self.r * self.T) * norm.cdf(-self.d2)
- self.S * norm.cdf(-self.d1))
def delta(self):
"""델타: 기초자산 가격 민감도"""
if self.type == 'call':
return norm.cdf(self.d1)
return norm.cdf(self.d1) - 1
def gamma(self):
"""감마: 델타의 변화율"""
return norm.pdf(self.d1) / (self.S * self.sigma * np.sqrt(self.T))
def theta(self):
"""세타: 시간가치 소멸 (일 단위)"""
term1 = -(self.S * norm.pdf(self.d1) * self.sigma)
/ (2 * np.sqrt(self.T))
if self.type == 'call':
term2 = -self.r * self.K * np.exp(-self.r * self.T)
* norm.cdf(self.d2)
else:
term2 = self.r * self.K * np.exp(-self.r * self.T)
* norm.cdf(-self.d2)
return (term1 + term2) / 365
def vega(self):
"""베가: 변동성 민감도 (1% 변동 기준)"""
return self.S * norm.pdf(self.d1) * np.sqrt(self.T) / 100
def rho(self):
"""로: 금리 민감도"""
if self.type == 'call':
return self.K * self.T * np.exp(-self.r * self.T)
* norm.cdf(self.d2) / 100
return -self.K * self.T * np.exp(-self.r * self.T)
* norm.cdf(-self.d2) / 100
# 사용 예시
opt = BlackScholes(S=100, K=105, T=0.25, r=0.05, sigma=0.2, option_type='call')
print(f"옵션가: {opt.price():.4f}")
print(f"델타: {opt.delta():.4f}")
print(f"감마: {opt.gamma():.4f}")
print(f"세타: {opt.theta():.4f} (일)")
print(f"베가: {opt.vega():.4f}")
print(f"로: {opt.rho():.4f}")
그릭스 시각화: 행사가·만기별 변화
그릭스는 고정된 값이 아니라 시장 조건에 따라 실시간으로 변합니다. 특히 만기 근접 시 감마가 급등하고, ATM(등가격) 부근에서 델타 변화가 가장 큼을 이해해야 합니다.
import matplotlib.pyplot as plt
def plot_greeks_by_spot(K=100, T=0.25, r=0.05, sigma=0.2):
"""기초자산 가격별 그릭스 변화 시각화"""
spots = np.linspace(70, 130, 200)
greeks = {'delta': [], 'gamma': [], 'theta': [], 'vega': []}
for s in spots:
opt = BlackScholes(s, K, T, r, sigma)
greeks['delta'].append(opt.delta())
greeks['gamma'].append(opt.gamma())
greeks['theta'].append(opt.theta())
greeks['vega'].append(opt.vega())
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
titles = ['Delta', 'Gamma', 'Theta', 'Vega']
for ax, (name, vals), title in zip(axes.flat, greeks.items(), titles):
ax.plot(spots, vals, linewidth=2)
ax.axvline(K, color='red', linestyle='--', alpha=0.5, label='행사가')
ax.set_title(title, fontsize=14)
ax.set_xlabel('기초자산 가격')
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('greeks_plot.png', dpi=150)
plt.show()
델타 헤지: 방향성 리스크 제거
델타 헤지(Delta Hedging)는 옵션 포지션의 방향성 리스크를 기초자산 매매로 상쇄하는 전략입니다. 옵션 매도자(마켓메이커)가 가장 많이 사용하는 헤지 기법입니다.
| 포지션 | 델타 | 헤지 행동 |
|---|---|---|
| 콜 매도 1계약 (델타 -0.5) | -50 | 기초자산 50주 매수 |
| 풋 매도 1계약 (델타 +0.4) | +40 | 기초자산 40주 매도 |
| 콜 매수 + 풋 매수 (스트래들) | ≈0 | 이미 델타 중립 |
class DeltaHedger:
"""델타 헤지 시뮬레이터"""
def __init__(self, K, T, r, sigma, contracts=1, multiplier=100):
self.K = K
self.T = T
self.r = r
self.sigma = sigma
self.contracts = contracts
self.multiplier = multiplier
self.hedge_history = []
def required_shares(self, S, t):
"""헤지에 필요한 기초자산 수량"""
remaining = max(self.T - t, 1e-6)
opt = BlackScholes(S, self.K, remaining, self.r, self.sigma)
delta = opt.delta()
return round(delta * self.contracts * self.multiplier)
def simulate(self, prices, dt=1/252):
"""일별 델타 헤지 시뮬레이션"""
shares_held = 0
cash = 0
t = 0
# 초기 옵션 프리미엄 수취 (매도 포지션)
opt = BlackScholes(prices[0], self.K, self.T, self.r, self.sigma)
premium = opt.price() * self.contracts * self.multiplier
cash += premium
for i, price in enumerate(prices):
t = i * dt
target = self.required_shares(price, t)
trade = target - shares_held
# 기초자산 매매로 델타 조정
cash -= trade * price
shares_held = target
# 포트폴리오 가치 계산
remaining = max(self.T - t, 1e-6)
opt = BlackScholes(price, self.K, remaining, self.r, self.sigma)
option_value = opt.price() * self.contracts * self.multiplier
portfolio_value = cash + shares_held * price - option_value
self.hedge_history.append({
'day': i,
'price': price,
'delta': opt.delta(),
'shares': shares_held,
'trade': trade,
'portfolio': portfolio_value,
'hedge_cost': abs(trade) * price * 0.001 # 거래비용
})
return self.hedge_history
# 시뮬레이션 실행
np.random.seed(42)
S0 = 100
days = 63 # 3개월
returns = np.random.normal(0.0002, 0.015, days)
prices = S0 * np.cumprod(1 + returns)
hedger = DeltaHedger(K=100, T=0.25, r=0.05, sigma=0.2)
results = hedger.simulate(prices)
final = results[-1]
print(f"최종 포트폴리오 가치: {final['portfolio']:,.2f}")
print(f"총 리밸런싱 횟수: {sum(1 for r in results if r['trade'] != 0)}")
델타 헤지의 핵심은 리밸런싱 빈도입니다. 너무 자주 하면 거래비용이 수익을 초과하고, 너무 드물면 헤지가 부정확해집니다. 변동성 타겟팅 전략과 결합하면 리밸런싱 시점을 최적화할 수 있습니다.
내재변동성 역산: 시장이 말하는 변동성
옵션 시장 가격에서 내재변동성(Implied Volatility)을 역산하는 것은 퀀트 트레이딩의 핵심 기술입니다. Newton-Raphson 방법으로 빠르게 수렴합니다.
def implied_volatility(market_price, S, K, T, r, option_type='call',
tol=1e-6, max_iter=100):
"""Newton-Raphson 내재변동성 역산"""
sigma = 0.2 # 초기 추정치
for _ in range(max_iter):
opt = BlackScholes(S, K, T, r, sigma, option_type)
price = opt.price()
vega = opt.vega() * 100 # 원래 스케일 복원
if abs(vega) < 1e-10:
break
diff = price - market_price
if abs(diff) < tol:
return sigma
sigma -= diff / vega
sigma = max(sigma, 0.001) # 음수 방지
return sigma
# 사용 예시
iv = implied_volatility(
market_price=5.50, S=100, K=105, T=0.25, r=0.05
)
print(f"내재변동성: {iv:.2%}")
내재변동성 표면(Volatility Surface)을 구성하면 행사가·만기별 시장의 기대를 한눈에 파악할 수 있습니다. 이를 통해 상대적으로 저평가된 옵션을 찾는 변동성 차익거래 기회를 포착할 수 있습니다.
실전 포트폴리오 그릭스 관리
실전에서는 여러 옵션을 동시에 보유하므로 포트폴리오 전체의 그릭스를 관리해야 합니다.
class PortfolioGreeks:
"""멀티 옵션 포트폴리오 그릭스 집계"""
def __init__(self):
self.positions = []
def add_position(self, S, K, T, r, sigma, option_type, quantity):
self.positions.append({
'option': BlackScholes(S, K, T, r, sigma, option_type),
'quantity': quantity
})
def net_greeks(self):
"""포트폴리오 순 그릭스"""
total = {'delta': 0, 'gamma': 0, 'theta': 0, 'vega': 0}
for pos in self.positions:
opt = pos['option']
q = pos['quantity']
total['delta'] += opt.delta() * q * 100
total['gamma'] += opt.gamma() * q * 100
total['theta'] += opt.theta() * q * 100
total['vega'] += opt.vega() * q * 100
return total
def hedge_recommendation(self):
"""델타·감마 헤지 추천"""
greeks = self.net_greeks()
recs = []
if abs(greeks['delta']) > 5:
shares = -round(greeks['delta'])
recs.append(f"기초자산 {shares:+d}주로 델타 헤지")
if abs(greeks['gamma']) > 1:
recs.append(f"감마 {greeks['gamma']:+.1f} → ATM 옵션으로 감마 헤지 필요")
if not recs:
recs.append("그릭스 중립 — 추가 헤지 불필요")
return recs
# 포트폴리오 구성 예시
port = PortfolioGreeks()
port.add_position(100, 100, 0.25, 0.05, 0.2, 'call', -10) # 콜 10계약 매도
port.add_position(100, 95, 0.25, 0.05, 0.22, 'put', -5) # 풋 5계약 매도
greeks = port.net_greeks()
print(f"포트폴리오 그릭스: {greeks}")
for rec in port.hedge_recommendation():
print(f" → {rec}")
그릭스 관리의 목표는 원하는 리스크만 남기고 나머지는 헤지하는 것입니다. 예를 들어 변동성 매도 전략은 베가를 음수로 유지하면서 델타와 감마를 중립으로 만듭니다. 리스크 패리티 포트폴리오 원리와 결합하면 더 정교한 리스크 배분이 가능합니다.
그릭스 트레이딩 실전 팁
- 감마 스캘핑: 높은 감마를 보유하고 기초자산 가격 변동 시 델타 리밸런싱으로 수익 — 세타 비용과의 균형이 관건
- 베가 트레이딩: 내재변동성이 실현변동성보다 높을 때 옵션 매도 — 변동성 프리미엄 수취 전략
- 세타 수확: 만기 가까운 OTM 옵션 매도로 시간가치 소멸 수익 — 꼬리 리스크 관리 필수
- 리밸런싱 임계값: 델타 변화가 일정 수준(예: ±10) 초과 시에만 헤지 — 거래비용 최소화
옵션 그릭스는 퀀트 트레이딩의 가장 정교한 리스크 관리 도구입니다. Black-Scholes 모델로 기본기를 다지고, 실전에서는 변동성 표면, 점프 리스크, 유동성까지 고려한 확장 모델을 적용하세요.