아래의 글
2022.11.17 - [금융이야기] - 키움 ELS 1호의 화끈한 신고식!
에서 다룬 ELS (키움 ELS1호)가 천신만고 끝에 상환되었음을 이야기했습니다.
2010.9월 키움증권에서 ELS를 론칭하는데, 그 수익률이 무리 년 30%이었습니다. 3년에 만기 상환되면 무려 90%의 수익률을 자랑했었죠.
KT와 현대미포조선을 기초자산으로 하였는데, 중간 결과는 신통치 않았습니다. 5번의 조기상환 기회를 그냥 날리고, 무려 중간에 낙인 배리어까지 터치하는 등 퍼포먼스가 저조했었죠.
하지만, 꾸역꾸역 회복하던 주가는 마침내 만기상환 배리어를 극적으로 상회하며 90% 수익상환으로 막을 내리게 됩니다.
이 글의 목적은
키움 ELS1호는 만기 근처에 그 가격이 얼마를 형성하고 있었을까?
를 알아보기 위함입니다. 원래 ELS는 다양한 조기상환과 낙인 배리어까지 고려해야 하고, 두 가지 자산이 움직이므로 가격을 계산하기가 어렵습니다. 하지만, 낙인을 이미 쳤고, 만기상환밖에 안 남은 시점에서는 가격을 계산하기가 수월해집니다.
스텝다운 ELS에서 설명한 복잡한 ELS 구조에서 아래 그림의 수익구조만 남습니다.
얼마나 무시무시하냐면, 100억을 투자한 사람이 있을 때,
○ 워스트포퍼머가 80 배리어를 조금이라도 넘기면 90억의 수익 발생 : 원금 포함 총 190억원 획득
○ 워스트 포퍼머가 80을 하회하면 최소 20억 손실 즉, 최대 80억 밖에 못 건지는 상황
안팎으로 110억에 워스트 포퍼머의 움직임이 달려있던 상황이었죠.
만기 5일 전부터의 상황을 정리해 보면 이렇습니다.
잔존만기 | 일자 | 현대미포조선 퍼포먼스 |
KT 퍼포먼스 |
워스트포퍼머 |
만기 5일전 | 2013-08-23 | 0.802 | 0.789 | 0.789 |
만기 4일전 | 2013-08-26 | 0.801 | 0.787 | 0.787 |
만기 3일전 | 2013-08-27 | 0.806 | 0.785 | 0.785 |
만기 2일전 | 2013-08-28 | 0.810 | 0.787 | 0.787 |
만기 1일전 | 2013-08-29 | 0.811 | 0.795 | 0.795 |
만기 | 2013-08-30 | 0.812 | 0.806 | 0.806 |
(만기 때 워스트 퍼포머가 0.8을 상회하며 수익 상환되는 모습)
자 이제 ELS 가격을 구해 보겠습니다.
ELS의 가격 구하는 과정
1. 주가 패스를 만들기 위한 파라미터 산출
저 당시 현대미포조선과 KT의 역사적 변동성(180일) 상관계수를 구하고, 그 당시 CD91 금리 등을 조사했더니 다음과 같은 파라미터가 산출되었습니다. (배당은 없다고 가정했습니다.)
구분 | 현대미포조선 | KT |
변동성 | 30.1% | 23.2% |
상관계수 | 0.04 | |
무위험 이자율 | 2.5% |
2. 만기 때 종가를 GBM으로 산출
현대미포조선과 KT의 퍼포먼스를 $X_t, Y_t$, 변동성을 각각 $\sigma_X, \sigma_Y$, 현재가를 각각 $X_0, Y_0$ 라 하면 시점 $t$의 퍼포먼스는 각각
$$
\begin{align}
X_t &=X_0 \exp\left( (r-0.5\sigma_X^2)t + \sigma_X \sqrt{t}w_X\right)\\
Y_t &=Y_0 \exp\left( (r-0.5\sigma_Y^2)t + \sigma_Y \sqrt{t}w_Y\right)
\end{align}
$$
이고 $w_X , w_Y$는 서로 상관계수가 $\rho$인 표준정규분포 난수입니다. 따라서 서로 독립인 표준정규분포 $z_X, z_Y$를 뽑아
$$ w_X = z_X ~,~ w_Y = \rho z_X +\sqrt{1-\rho^2} z_Y $$
로 생성할 수 있습니다 ( [수학의 재미/행렬 이론] - 촐레스키 분해를 참고하시기 바랍니다.)
3. 워스트퍼포머를 산출하여 배리어와 비교, 수익 계산하기
$$ m_t = \min ( X_t , Y_t)$$
와 같이 만기 때 워스트포퍼머 $m_t$ 를 산출한 후 이 친구를 배리어와 비교합니다. 넘으면 90% 수익, 아니면 워스트포퍼머만큼 손실인 것이죠. 수식으로 쓰면
$$
\text{payoff} =
\begin{cases}
90\% &,& m_t \geq 80\%\\
m_t-1 &,& otherwise
\end{cases}
$$
입니다.
4. 2~3 과정을 많이 반복하여 수익 데이터 많이 산출 후 평균(MonteCarlo Simulation)
몬테카를로 시뮬레이션을 위해 2~4를 가능한 많이 반복하여 수익 데이터를 많이 뽑아냅니다. 그런 후 이를 평균하면 평균 수익이 나오게 되죠.
자세한 내용은 시뮬레이션 설명을 참고해 보시기 바랍니다.
5. 4에서 구한 값을 현재가치로 할인하기
구하고자 하는 시점에 형성된 무위험 이자율 $r$과 잔존 만기 $t$에서 얻어지는 할인 팩터
$$ \exp(-r\cdot t)$$
를 4에서 구한 값에 곱해주어 현재가치로 할인합니다. 바로 이 값이 ELS의 공정가치가 됩니다.
파이썬 코딩
파이썬으로 이 상황을 코딩하여 보겠습니다.
import numpy as np
from scipy.stats import multivariate_normal
from scipy.stats import norm
def kiwoom_lastChance():
spot_series = np.array([[0.802, 0.789],
[0.801, 0.787],
[0.806, 0.785],
[0.81, 0.787],
[0.811, 0.795],
[0.812, 0.806]
])
maturity = np.array([5, 4, 3, 2, 1, 0])
vol = np.array([0.301, 0.232])
rho = 0.04
rfr = 0.025
drift = rfr - 0.5 * vol ** 2
barrier = 0.8
coupon = 0.9
np.random.seed(seed=0)
norm_rand = np.random.normal(size=(10000, 2))
norm_rand_correlated = norm_rand
norm_rand_correlated[:, 1] = rho * norm_rand[:, 0] + np.sqrt(1 - rho ** 2) * norm_rand[:, 1]
for s, t in zip(spot_series, maturity):
s_expected = s * np.exp(drift * t / 365 + vol * np.sqrt(t / 365) * norm_rand_correlated)
worst_performer = np.min(s_expected, axis=1)
payoff = np.where(worst_performer >= barrier, coupon, worst_performer - 1)
payoff_average = payoff.mean()
val = np.exp(-rfr * t) * payoff_average
print('time to maturity: {} day. Values is {:.3f}'.format(t, val))
if __name__ == '__main__':
kiwoom_lastChance()
간략히 살펴보겠습니다.
spot_series = np.array([[0.802, 0.789],
[0.801, 0.787],
[0.806, 0.785],
[0.81, 0.787],
[0.811, 0.795],
[0.812, 0.806]
]) #만기 5일전부터 만기때까지 두 기초자산의 퍼포먼스 : 현재가 역할을 함
maturity = np.array([5, 4, 3, 2, 1, 0]) #만기 5일전~ 0일전
vol = np.array([0.301, 0.232]) # 각 자산의 변동성
rho = 0.04 # 자산 간 상관계수
rfr = 0.025 # 무위험 이자율
drift = rfr - 0.5 * vol ** 2 # GBM 에서 drift 항
barrier = 0.8 # 만기상환 배리어
coupon = 0.9 # 만기시 지급쿠폰
np.random.seed(seed=0) # seed 고정
norm_rand = np.random.normal(size=(10000, 2)) #10000개의 워스트 포퍼머를 산출할 예정, 열의 2인 자산의 개수
norm_rand_correlated = norm_rand
norm_rand_correlated[:, 1] = rho * norm_rand[:, 0] + np.sqrt(1 - rho ** 2) * norm_rand[:, 1]
# Cholesky 분포로 correlated 된 난수를 산출
for s, t in zip(spot_series, maturity): # 만기 t일 전의 기초자산 퍼포먼스를 s라 하여 for문 돌림
s_expected = s * np.exp(drift * t / 365 + vol * np.sqrt(t / 365) * norm_rand_correlated)
# GBM 으로 만기 종가 생성 : s_expected는 2 원소로 이루어진 배열
worst_performer = np.min(s_expected, axis=1)
# 행방향으로 min을 구해서 각각의 worst_performer 10000개를 구함
payoff = np.where(worst_performer >= barrier, coupon, worst_performer - 1)
# where문을 이용하여 worst performer에 따른 수익 산출
payoff_average = payoff.mean()
# 수익의 기댓값 산출
val = np.exp(-rfr * t) * payoff_average # 수익기댓값을 할인
print('time to maturity: {} day. Values is {:.3f}'.format(t, val))
결과를 보겠습니다.
time to maturity: 5 day. Values is -0.035
time to maturity: 4 day. Values is -0.069
time to maturity: 3 day. Values is -0.090
time to maturity: 2 day. Values is -0.081
time to maturity: 1 day. Values is 0.062
time to maturity: 0 day. Values is 0.900
결과가 어떤가요? 만기 5일 전에는 예상손익이 손실 -3.5%, 4일 전에는 -6.9% 이러다가 만기 하루 전에는 6.2% 수익.. 이런 식이었습니다. 즉, 분명히 90%의 수익을 챙길 확률이 있는데도, 손실 가능성도 역시 크게 보고 있었다는 얘기죠.
이를 피부로 느끼기 위해 실제 투자 집행된 50억을 이 ELS의 발행금액이라 가정해 봅시다.
일자 | 손익기대율 | 50억 투자시 기대손익(억원) |
50억 투자시 상환금액(억원) |
만기 5일전 | -3.50% | -1.75 | 48.25 |
만기 4일전 | -6.90% | -3.45 | 46.55 |
만기 3일전 | -9.00% | -4.5 | 45.5 |
만기 2일전 | -8.10% | -4.05 | 45.95 |
만기 1일전 | 6.20% | 3.1 | 53.1 |
만기 | 90.00% | 45 | 95 |
바로 전날까지 만기 기대수익이 3.1억 밖에 안되었습니다. 이를 헤지 운용한 증권사는 아주 잘 쳐줘야 3.1억만 만들어놓은 상황일 테고요. 그런데 주식이 오르면서 실제 실현된 수익이 45억으로 뻥튀기되면서, 이를 고객에게 원금 50억과 함께, 총 95억을 지급해야 됩니다.
발행 증권사는 아무리 잘했어도 막판 기초자산 움직임 한 틱 때문에 42억 정도가 갑자기 손실로 터진 상황
입니다. 어쩌면 훨씬 더 될지도 모르죠. 헤지운용으로 만들어내지 못한 금액 42억(45 - 3.1)은 당연히 회사 돈으로 줄 수밖에 없죠.
ELS의 이러한 현상, 즉, 손익 구조의 급격한 변화에 의해 헤지 운용이 잘 안되고 손실이 발행하는 위험을 핀 리스크라 합니다, ELS의 핀리스크는 조기상환이 순연될수록 커지며, 만기로 다가올수록 더 증가하게 됩니다. 엎친데 덮친 격으로 낙인을 친 기초자산들이 회복하여 수익 배리어를 상회하게 되는 날이면, 그 손실은 걷잡을 수 없이 증가할 가능성이 있습니다.
'금융공학' 카테고리의 다른 글
Brownian bridge: 1년뒤 주가타겟을 정조준하는 일일주가의 움직임을 모델링하자 #2 (0) | 2022.11.24 |
---|---|
Brownian bridge: 1년뒤 주가타겟을 정조준하는 일일주가의 움직임을 모델링하자 #1 (0) | 2022.11.24 |
스텝다운 ELS (0) | 2022.11.16 |
워스트 퍼포머(worst performer)의 분포 #2 : Python Code (0) | 2022.10.26 |
워스트 퍼포머(worst performer)의 분포 #1 (0) | 2022.10.26 |
댓글