본문 바로가기
금융공학

옵션 #7. 옵션 프리미엄 구하기 실습: Binomial Tree

by hustler78 2022. 8. 22.
728x90
반응형

 

 

이번 글에서는

2022.08.21 - [금융공학] - 옵션 #6. 옵션 프리미엄 구하기 실습: MonteCarlo Simulation

 

옵션 #6. 옵션 프리미엄 구하기 실습: MonteCarlo Simulation

이번 글은 2022.08.19 - [금융공학] - 옵션 #5. 옵션 프리미엄 구하기 실습: 함축적 FDM 옵션 #5. 옵션 프리미엄 구하기 실습: 함축적 FDM 지난 글 2022.08.19 - [금융공학] - 옵션 #4. 옵션 프리미엄 구하기 실

sine-qua-none.tistory.com

에 이어서 콜옵션의 가격을 다른 방법으로 구해보겠습니다. 바로 binomial tree로 구하는 방법입니다. 우선, binomial tree를 복습해 보겠습니다.

 

 

Binomial Tree  복습

주식은 상승(상승률 $u$), 하락(하락률 $d$) 두 가지 상태이고, $ud=1$ 을 만족하며 GBM의 기댓값과 분산을 만족하도록 상승확률 $p$와 하락 확률 $1-p$를 설계하며 다음과 같았습니다.

 

너무 지겹게 등장해, 이제 외울떄도 될만한 그림

이러한 이항 모델(binomial model)을 붙여 아래와 같이 이항트리를 만들었지요.

 

가로축은 시점 축, 세로축은 기초자산의 축입니다. 시점 $n$에서 상승횟수가 $i$인 주가의 값은

$$ S_0 u^i d^{n-i}$$

입니다($S_0$는 현재주가)

 

파생상품의 가격은 다음과 같이 구합니다.

시점 step $n$번째의 아래서부터 $i$번째 노드는 기초자산의 가격이 $ S_0 u^{i}d^{n-i}$ 이고 이때의 파생상품의 가격을 $ f(n,i), 0\leq n\leq N, 0\leq i\leq N$이라 쓰면

○ $f(N,i)$ 는 만기 시점 페이오프(위 그림에서 가장 오른쪽 노드들)
○ $ f(n,i) = e^{-r\Delta t} \left[ p f(n+1,i+1) + (1-p) f(n+1,i)\right]$ 의 점화식을 만족
○ $ f(0,0)$ 이 바로 현재 시점, 현재 주가 에서의 파생상품의 가치

 

 

 

 

콜옵션의 가격 구하기

 

위의 그림에서 만기 $T$, 행사가 $K$인 콜옵션의 만기 페이오프는, 모든 $i\leq N$에 대해

$$f(N,i) = \max(S_0 u^i d^{N-i} - K ,0)$$ 입니다. $N$은 $t_N=T$인 끝 index입니다.

 

 

python code입니다. 기본적으로 델타원 상품 가격을 구한 글에 수록된 코드 예제와 상당히 유사합니다. 비교해 보시기 바랍니다. 

 

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
import time

N = norm.cdf


def CallOptionBS(S, K, T, r, q, sigma):
    if T == 0:
        return np.max(S - K, 0)
    else:
        d1 = (np.log(S / K) + (r - q + sigma ** 2 / 2) * T) / (sigma * np.sqrt(T))
        d2 = d1 - sigma * np.sqrt(T)
        return S * np.exp(-q * T) * N(d1) - K * np.exp(-r * T) * N(d2)


def call_option_by_BinomialTree():
    s0 = 100
    vol = 0.3
    r = 0.02
    q = 0.01
    maturity = 1
    strike = 100
    nNode = 20
    dt = maturity / nNode

    u = np.exp(vol * np.sqrt(dt))
    d = 1 / u
    a = np.exp((r - q) * dt)
    p = (a - d) / (u - d)

    def treeNode(n, i):
        if n == nNode:
            return np.max([s0 * u ** i * d ** (n - i) - strike, 0])
            # return np.max([s0 * u ** (2 * i - n) - strike, 0])
        elif n < nNode:
            up_val = treeNode(n + 1, i + 1)
            down_val = treeNode(n + 1, i)
            df = np.exp(-r * dt)
            return (p * up_val + (1 - p) * down_val) * df

    start_time = time.time()
    res = treeNode(0, 0)
    elapsed_time = time.time()-start_time
    print('Binomial Tree price : {:.3f}'.format(res))
    print('excat         price : {:.3f}'.format(CallOptionBS(s0, strike, maturity, r, q, vol)))
    print('calculation time    : {:.2f}'.format(elapsed_time))


if __name__ == '__main__':
    call_option_by_BinomialTree()

 

코드를 간략하게 분석해 보겠습니다.

import time	# 계산에 소요된 시간을 분석하기 위해 필요한 time 모듈

 


    u = np.exp(vol * np.sqrt(dt))	# 이항모델 세팅: 주가의 상승률
    d = 1 / u			# 이항모델 세팅: 주가의 하락률
    a = np.exp((r - q) * dt)
    p = (a - d) / (u - d)	# 주가의 상승확률

 


    def treeNode(n, i):	#binomial tree의 노드의 값들을 재귀적으로 계산하기 위해 만든 함수
        if n == nNode:	# 만기시에는,
            return np.max([s0 * u ** i * d ** (n - i) - strike, 0])	# 만기 payoff을 대입한다.
            # return np.max([s0 * u ** (2 * i - n) - strike, 0])	# 만기 payoff을 u에 관해 정리한 식
        elif n < nNode:
            up_val = treeNode(n + 1, i + 1)
            down_val = treeNode(n + 1, i)
            df = np.exp(-r * dt)
            return (p * up_val + (1 - p) * down_val) * df	#점화식을 사용하여 전단계 timestep의 값 산출

○ $u^i d^{n-i} = u^i u^{-(n-i)} = u^{2i-n}$ 이므로 주가의 상태를 $u$에 관해 정리할 수 있습니다.

 


    start_time = time.time()	#계산 시작 시점의 시각을 읽는다
    res = treeNode(0, 0)
    elapsed_time = time.time()-start_time	#계산 끝난 시각(time.time())을 읽어 계산시작 시점을 뺀 값

 

 

결과를 보겠습니다.

Binomial Tree price : 12.099
excat         price : 12.245
calculation time    : 9.94

Process finished with exit code 0

Binomial Tree로 계산해도 Black Scholes Formula로 구한 결과와 거의 유사하죠?

 

Binomail Tree로 계산해 보니 한 가지 단점이 시간이 쫌 걸린다는 사실입니다. nNode =20으로 잡아도 10초 안팎으로 걸리는군요. 사실 nNode =20이라는 얘기는 maturity = 1년을 20등분 한 것으로 근 18(=365일/20) 간격으로 이산화 시킨 것입니다. 따라서 생각보다 성기게 이산화를 시킨 건데요. 계산 시간이 좀 많이 걸립니다.

 

Node 별로 파생상품의 가치가 어떻게 변화하는지 시각적으로 분석하고 싶을 때는 아무래도 엑셀 VBA로 산출해 보는 것이 유용합니다. 다음 글에서는 엑셀 VBA를 사용하여 콜옵션의 binomial tree를 시각적으로 분석해 보겠습니다. 

 

 

 

 

728x90
반응형

댓글