이번 글은 UOC(Up and Out Call option) 상품을 Binomial Tree로 구해보는 내용으로써
2022.08.29 - [금융공학] - 배리어옵션 - UOC 옵션 #4 MonteCarlo Simulation
에서 이어집니다. 우선 Binomial Tree를 복습해보고, UOC의 가격을 계산할 때는 어떤 점을 주의해야 하는지 알아보겠습니다.
Binomial Tree 복습
주식은 상승(상승률 $u$), 하락(하락률 $d$) 두 가지 상태이고, $ud=1$ 을 만족하며 GBM의 기댓값과 분산을 만족하도록 상승확률 $p$와 하락 확률 $1-p$를 설계하며 다음과 같았습니다.
이러한 이항 모델(binomial model)을 붙여 다음처럼 이항 트리를 만듭니다.
○ 만기까지 $N$개의 time step으로 분할합니다.
○ $n$번째 time step에는 $n$개의 주가분포가 있는데 $ S_0 u^i d^{n-i}, 0\leq i\leq n$ 형태입니다.
○ 각 node에서 결정된 파생상품 값을 $f(n,i)$라 하면
○ $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(n,i)$ 를 위의 점화식으로 구한 뒤, 배리어 위쪽에 위치한 노드의 값은 리베이트로 대체(중요!)
○ $ f(0,0)$ 이 바로 현재 시점, 현재 주가 에서의 파생상품의 가치
UOC 가격 계산 Python Code
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
import time
N = norm.cdf
def UOC_by_BinomialTree(s0, strike, maturity, upBarrier, rfr, vol, div, rebate):
nNode = 1000
dt = maturity / nNode
u = np.exp(vol * np.sqrt(dt))
d = 1 / u
a = np.exp((rfr - div) * dt)
p = (a - d) / (u - d)
valueNode = np.zeros((nNode + 1, nNode + 1))
for n in reversed(range(nNode + 1)):
for i in range(n + 1):
spotS = s0 * u ** i * d ** (n - i)
if n == nNode:
if spotS > upBarrier:
valueNode[n, i] = rebate
else:
valueNode[n, i] = np.max([spotS - strike, 0])
else:
if spotS > upBarrier:
valueNode[n, i] = rebate
else:
up_val = valueNode[n + 1, i + 1]
down_val = valueNode[n + 1, i]
df = np.exp(-rfr * dt)
valueNode[n, i] = (p * up_val + (1 - p) * down_val) * df
return valueNode[0, 0]
def calculate_UOC():
s0 = 100
strike = 100
maturity = 1
upBarrier = 120
rfr = 0.02
vol = 0.2
div = 0.01
rebate = 3
uoc_value_binomial_tree = UOC_by_BinomialTree(s0, strike, maturity,upBarrier,rfr,vol,div,rebate)
print('UOC_value_Binomial tree: {}'.format(uoc_value_binomial_tree))
print('UOC_value_ClosedForm: {}'.format(UOcall_ClosedForm(s0, strike, maturity, upBarrier, rfr, vol, div, rebate)))
if __name__ == '__main__':
calculate_UOC()
Binomial Tree 구현하는 부분을 검토해 보겠습니다.
def UOC_by_BinomialTree(s0, strike, maturity, upBarrier, rfr, vol, div, rebate):
nNode = 1000 # time step를 1000개로 쪼개고
dt = maturity / nNode # 시점 간격을 dt로 정의합니다.
u = np.exp(vol * np.sqrt(dt)) # 이항모델의 u,d 및 p를 계산하고
d = 1 / u
a = np.exp((rfr - div) * dt)
p = (a - d) / (u - d)
valueNode = np.zeros((nNode + 1, nNode + 1)) # 각 node의 값 저장을 위해 2차원 배열 정의
for n in reversed(range(nNode + 1)): # n을 역순으로 감소시키면서 0까지 for문 돌리며
for i in range(n + 1):
spotS = s0 * u ** i * d ** (n - i) #각 주가node에 주가를 정의하고
if n == nNode: # 만일 만기시점이면
if spotS > upBarrier: # 배리어 위에서 리베이트를
valueNode[n, i] = rebate
else:
valueNode[n, i] = np.max([spotS - strike, 0]) #배리어 밑에서 콜옵션페이오프를
else:
if spotS > upBarrier:
valueNode[n, i] = rebate #배리어 위에서는 rebate
else:
up_val = valueNode[n + 1, i + 1]
down_val = valueNode[n + 1, i]
df = np.exp(-rfr * dt)
valueNode[n, i] = (p * up_val + (1 - p) * down_val) * df # 배리어 밑에서 점화식으로
return valueNode[0, 0] #현재시점 현재가에서의 node가격을 return함
결과를 보겠습니다.
UOC_value_Binomial tree: 2.150678731567234
UOC_value_ClosedForm: 2.1397093466460846
아주 좋은 결과를 얻었습니다. Closed form의 결과와 상당히 유사하죠.
참고 사항
2022.08.22 - [금융공학] - 옵션 #7. 옵션 프리미엄 구하기 실습: Binomial Tree에서 옵션의 가격을 Binomial Tree로 계산할 때, 재귀적 함수 형식으로 코딩하였습니다. 즉,
def UOC_by_BinomialTree_recursiveform(s0, strike, maturity, upBarrier, rfr, vol, div, rebate):
nNode = 20
dt = maturity / nNode
u = np.exp(vol * np.sqrt(dt))
d = 1 / u
a = np.exp((rfr - div) * dt)
p = (a - d) / (u - d)
def treeNode(n, i):
spotS = s0 * u ** i * d ** (n - i)
if n == nNode:
if spotS > upBarrier:
return rebate
else:
return np.max([spotS - strike, 0])
# return np.max([s0 * u ** (2 * i - n) - strike, 0])
elif n < nNode:
if spotS > upBarrier:
return rebate
else:
up_val = treeNode(n + 1, i + 1)
down_val = treeNode(n + 1, i)
df = np.exp(-rfr * dt)
return (p * up_val + (1 - p) * down_val) * df
start_time = time.time()
res = treeNode(0, 0)
elapsed_time = time.time() - start_time
return res
위와 같이 함수 treeNode 안에 또 treeNode를 구현하는 형식으로 코딩을 했었죠. 그런데, 이 방법이 계산시간이 하세월이 걸리는 겁니다. 코드의 어느 부분이 잘못됐는지, 아님 재귀적 함수 사용 알고리즘이 원래 시간을 많이 잡아먹는 건지.. 어쨌든 계산시간이 너무 걸려 부득불 본문처럼 valueNode라는 배열을 선언하여 다시 코딩했더니 거의 실시간 계산이 가능했습니다. 이러한 현상을 좀 더 공부해 봐야겠습니다.
이로써, UOC 옵션의 가격에 대해서 글을 마치겠습니다. 다음 글에서는 더욱 유명한 파생상품을 소개해 보도록 하겠습니다.
'금융공학' 카테고리의 다른 글
디지털 옵션 #2. 디지털 옵션 Closed form 및 그래프 (0) | 2022.08.31 |
---|---|
디지털 옵션 #1. 디지털 옵션이란? 수학공식은? (0) | 2022.08.30 |
배리어옵션 - UOC 옵션 #4 MonteCarlo Simulation (0) | 2022.08.29 |
배리어옵션 -UOC 옵션 #3 이산화를 극복할 배리어 조정 (0) | 2022.08.26 |
배리어옵션 -UOC 옵션 #2 함축적 FDM (0) | 2022.08.25 |
댓글