본문 바로가기
금융공학

배리어옵션 -UOC 옵션 #1 수학공식(Closed form)

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

저번 글까지 파생상품의 대표주자 옵션의 프리미엄을 다양한 방법으로 구해 봤습니다. 참고로 옵션 가격 계산의 마지막 글은 2022.08.22 - [금융공학] - 옵션 #8. 옵션 프리미엄 구하기 실습: Binomial Tree(with VBA)

 

옵션 #8. 옵션 프리미엄 구하기 실습: Binomial Tree(with VBA)

지난 글 2022.08.22 - [금융공학] - 옵션 #7. 옵션 프리미엄 구하기 실습: Binomial Tree 옵션 #7. 옵션 프리미엄 구하기 실습: Binomial Tree 이번 글에서는 2022.08.21 - [금융공학] - 옵션 #6. 옵션 프리미엄..

sine-qua-none.tistory.com

입니다.

 

이번 글부터 다룰 파생상품은 배리어 옵션이라는 상품입니다. 배리어 옵션에는 여러 종류가 있으나 투자자들에게 가장 친숙한 형태의 옵션은 바로

 

Up and Out Call Option

입니다. 이것을 줄여서 UOC라 하겠습니다.

 

UOC 옵션이란?

 

말 그대로 주가가 오르면(up) 옵션의 성질이 없어지는(out) , Call option입니다. 그림을 살펴보도록 하죠.

 

구조를 좀 더 구체적으로 살펴볼까요?

○ UOC는 기본적으로 call option 이기 때문에 만기와 행사가 있습니다. 위 그림에서 행사가는 100입니다.

 

그런데 주가가 계속 상승(up)하여 어떤 수준(barrier, 그림에서는 120)를 한 번이라도 상회하면 그 즉시 이 옵션은 꺼지게(out) 됩니다. 옵션이 소멸되고 상품은 여기서 끝납니다. 대신에 아쉬우므로 rebate라는 개념의 약정 수익(그림에서는 3)을 옵션이 없어지는 날 보장해 주게 되는 거죠. 이 rebate는 보통 0이어서, 만일 배리어 이상을 치고 올라가면 옵션은 꽝이 됩니다.

 

이 상품은 우리나라 증권업계의 파생 비즈니스 하우스에서 엄청나게 많이 발행했던 상품입니다. 그만큼 이 상품을 좋아하는 투자자가 많았기 때문이죠. 그런데, 배리어를 한 번이라도 터치하면 옵션이 죽어 꽝이 되니 이런 상품에 왜 투자하나 싶기도 합니다.  하다 못해 ORIGINAL call option이랑만 비교해봐도 수익이 엄청 차이가 나는 걸 알 수 있지요. 무슨 말인고 하니,

위 그림은 UOC와 그냥 call option을 비교해 본 그래프입니다. call option 투자자는 UOC 투자자에 비해 회색영역 만큼의 수익 기회가 더 있는 거죠. 주가가 오르면 오를수록 만기 때 페이오프도 같이 증가하여 행복합니다. 그럼 왜 UOC에는 투자유인이 생기는 걸까요? 바로

 

UOC 옵션상품은 무지무지 값이 싸기 때문

 

입니다. 위 그림에서 주가가 배리어인 120을 넘으면 옵션이 소멸되는 조건때문에 UOC의 값은 엄청 싸질 수밖에 없습니다. 반면 운이 좋아 만기 때 종가가 119.9원으로 끝난다면, 거의 20의 수익을 먹을 수 있는 조건이지요. 

엄청 싼 값을 내고 최고의 수익 20을 노려볼만한 상품입니다. 최악의 경우에는 엄청 싼 프리미엄만큼만 손해인거지요.

 

자, 그럼 UOC의 가격은 어떻게 계산되는지 알아보겠습니다.

 

참고로 UOC는 Knock Out Call 상품이라고도 불립니다. 배리어를 노크(knock)하면 옵션이 죽는(Out) 다는 의미입니다.

 

 

 

UOC 수학공식은?

옵션 관련하여 가격 결정 방법을 집대성해 놓은 Haug의 "The Complete Guide to Option Pricing Formulas" 책이 있습니다.

 

이 책의 4.17절의 Starndard Barrier Options를 보면 해당 옵션의 공식이 나와있습니다.

두 번째 그림의 Up and Out Call 쪽을 보실까요? 지금 Option Out 되는 배리어가 현재가보다 높고 행사가가 배리어보다 낮은 상황이므로 

$$c_{uo}(X<H)$$ 파타를 중점적으로 보면 됩니다.

 

 

 

Python Code

위의 식을 그대로 python으로 구현해 보겠습니다.

 

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

N = norm.cdf

def UOcall_ClosedForm(s0, strike, maturity, upBarrier, rfr, vol, div, rebate):
    eta, phi = -1, 1
    volsqrMat = vol * np.sqrt(maturity)
    bb = rfr-div
    mu = (bb - vol * vol / 2) / (vol * vol)
    lmda = np.sqrt(mu ** 2 + 2 * rfr / vol ** 2)
    z = np.log(upBarrier / s0) / (volsqrMat) + lmda * volsqrMat

    x1 = np.log(s0 / strike) / volsqrMat + (1 + mu) * volsqrMat
    x2 = np.log(s0 / upBarrier) / volsqrMat + (1 + mu) * volsqrMat
    y1 = np.log(upBarrier ** 2 / (s0 * strike)) / volsqrMat + (1 + mu) * volsqrMat
    y2 = np.log(upBarrier / s0) / volsqrMat + (1 + mu) * volsqrMat

    A = phi * s0 * np.exp((bb - rfr) * maturity) * N(phi * x1)
    A += -phi * strike * np.exp(-rfr * maturity) * N(phi * x1 - phi * volsqrMat)

    B = phi * s0 * np.exp((bb - rfr) * maturity) * N(phi * x2)
    B += -phi * strike * np.exp(-rfr * maturity) * N(phi * x2 - phi * volsqrMat)

    C = phi * s0 * np.exp((bb - rfr) * maturity) * (upBarrier / s0) ** (2 * mu + 2) * N(eta * y1)
    C += -phi * strike * np.exp(-rfr * maturity) * (upBarrier / s0) ** (2 * mu) * N(eta * y1 - eta * volsqrMat)

    D = phi * s0 * np.exp((bb - rfr) * maturity) * (upBarrier / s0) ** (2 * mu + 2) * N(eta * y2)
    D += -phi * strike * np.exp(-rfr * maturity) * (upBarrier / s0) ** (2 * mu) * N(eta * y2 - eta * volsqrMat)

    E = N(eta * x2 - eta * volsqrMat)
    E += -(upBarrier / s0) ** (2 * mu) * N(eta * y2 - eta * volsqrMat)
    E *= rebate * np.exp(-rfr * maturity)

    F = (upBarrier / s0) ** (mu + lmda) * N(eta * z)
    F += (upBarrier / s0) ** (mu - lmda) * N(eta * z - 2 * eta * lmda * volsqrMat)
    F *= rebate

    result = A - B + C - D + F
    return result

def calculate_UOC():
    s0 = 100
    strike = 100
    maturity = 1
    upBarrier = 120
    rfr = 0.02
    vol = 0.2
    div = 0.01
    rebate = 3

    uoc_value = UOcall_ClosedForm(s0, strike, maturity, upBarrier, rfr, vol, div, rebate)
    print('exact formula : {}'.format(uoc_value))

if __name__ == '__main__':
    calculate_UOC()

 

수식을 그대로 옮겨 적은 거라 따로 설명은 필요하지 않을 것 같습니다.

 

 

결과는 다음과 같습니다.

 

exact formula : 2.1397093466460846

 

현재가 100원인 기초자산에 연동하는 파생상품의 가격이 2.14원입니다. 아주 싸죠. 만일 같은 조건에서 rebate를 0이라고 하면,

    rebate = 0

결과는

 

exact formula : 1.113016130848235

로 훨씬 싸지게 됩니다.

 

그러면 out 조건이 없는 동일한 콜옵션의 가격은 어찌 될까요? 위의 code에

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)

처럼 Black Scholes Formula를 추가하고

 

    print('call option price : {}'.format(CallOptionBS(s0, strike, maturity, rfr, div, vol)))

를 덧붙이면

 

call option price : 8.349405767096776

입니다. rebate가 없는 UOC대비 7.5배 정도 비싸죠.  따라서 싼 맛에 옵션 투자하는 투자자들에게 훌륭한 대응 상품이 되는 것입니다.

 

음영 영역의 값어치가 6.21 정도나 되네!!

 

수식이 복잡하여 식이 맞게 코딩이 되었는지 모르겠습니다. 이 때는 여러 방법으로 가격을 계산하여 cross check를 해봐야겠죠. 이어지는 글들에서 Binomial Tree나 MonteCarlo Simulation 등으로 위 값의 교차 검증을 해보겠습니다.

 

 

 

 

 

 

728x90
반응형

댓글