이번 글에서는 Brownian Bridge를 사용하여 주가 패스를 만드는 과정을 알아보겠습니다.
Brown Bridge를 만드는 방법은 [금융공학] - Brownian bridge: 1년 뒤 주가 타깃을 정조준하는 일일주가의 움직임을 모델링하자 #2 을 참고해 보시기 바랍니다.
목적
Brownian Bridge는 다음과 같은 문제를 해결하는데 주효합니다.
기초자산의 현재가가 $S_0=100$이고, 이것이 움직여 반년($T=0.5$) 뒤 주가가 $S_T=120$이라 할 때, 이 반 년 동안 하루하루의 주가 움직임은 어떻게 모델링할 수 있겠는가?
가정
○ 기초자산의 변동성 $\sigma = 30\%$, 배당은 없다고 가정
○ 무위험 이자율 $r=2\%$
○ 반 년동안 120日이 있다고 가정
시작점 $S_0$와 끝 점 $S_T$가 정해져 있으므로 중간중간의 교각을 세우려면 Brownian Bridge 기법을 사용해야 합니다.
해결 과정
해결과정은 GBM 모델링에서부터 시작합니다.
GBM 모델에서 시점 $T$에서의 위너프로세스 값 추출하기
GBM 모델을 사용하면
$$ S_T = S_0 \exp\left( (r-\frac12\sigma^2) T + \sigma Z(T) \right) \tag{1} $$
입니다. 여기서 $Z(\cdot)$는 이 GBM를 설명하는 위너프로세스이고, 배당은 없다고 가정했으므로, 연속 배당률 $q=0$입니다.
식(1)을 $Z(T)$에 관해 풀어보면,
$$ Z(T) = \frac{\ln(S_T/S_0) - (r-\frac12\sigma^2)T}{\sigma} \tag{2} $$
이죠.
이제 반 년을 일일 단위로 쪼갠 time grid를 만들어보죠.
일일 단위 time grid 설정
현재 시점 $t=0$에서 만기 시점 $t=T$까지 간격을 $N=120$개로 나눠 주면 됩니다. 즉 등간격으로
$$0=t_0<t_1<\cdots<t_{N-1}<t_N=T\tag{3}$$
의 time gride를 생각합니다. python으로 코딩하려면 numpy.linspace 함수를 쓰면 될 것 같네요.
식(3)의 time grid 시점 별로 Brownian Bridge 구하기
저번 글에 따르면, 식(2)에서 구한 $Z(T)$와 아예 새로운 위너 프로세스 $W(\cdot)$를 도입하여
$$B(t_i)=\frac{t_i}{T}Z(T)+W(t_i)-\frac{t_i}{T}W(T)$$
라 구하면, $B(t_i)$가 바로 시점 $t_i$에서의 위너프로세스 값이 된다고 하였고, 이게 바로 Brown Bridge라고 했습니다. 따라서 문제는
$$ W(t_1), W(t_2), \cdots, W(t_N)$$
를 구하면 되는 것인데, 이것은 아래와 같이 재귀적으로(recursively) 구해야 올바른 방법이라고 하였습니다.
$$ W(t_0)=0~,~ W(t_{i+1}) =W(t_i) +\epsilon_i \sqrt{\Delta t}$$
($\Delta t$는 time grid의 간격입니다.)
이제 python code로 이를 구현해 보겠습니다.
Python Code
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
def bb_GBM_test():
maturity = 0.5 # 만기 6m
nPath = 10 # 10개의 주가패스를 샘플로 그려볼 예정
ntime = 120 # 6m을 120일이라 가정하고 시간간격을 1/120 *0.5 =1/240으로 할 예정
time_grid = np.linspace(0, maturity, ntime + 1) #time을 120등분
s0 = 100 # 기초자산 현재가
s_target = 120 # 기초자산의 만기 타깃가격
vol = 0.3 # 변동성
rfr = 0.02 # 이자율
drift = rfr - 0.5 * vol ** 2 #drifr term
dt = time_grid[1] - time_grid[0]
# 타깃가격 s_target에서 추출한 위너프로세스 값 (Z(T))
norm_rand = (np.log(s_target / s0) - drift * maturity) / (vol)
plt.scatter(maturity, s_target)
for _ in range(nPath):
rn = np.zeros(ntime + 1)
for i in range(ntime): #Brownian Bridge 설계에 쓰일 난수 발생
rn[i + 1] = rn[i] + np.random.normal() * np.sqrt(time_grid[i + 1] - time_grid[i])
#Brownian Bridge 설계
brownian_bridge = norm_rand * time_grid / maturity + rn - time_grid / maturity * rn[-1]
s_path = s0 * np.exp(drift * time_grid + vol * brownian_bridge) #주가패스
plt.plot(time_grid, s_path)
plt.pause(1) #1초에 하나씩 패스그리기
plt.show()
if __name__ == '__main__':
bb_GBM_test()
결과를 볼까요?
다음과 같이 멋진 10개의 패스를 그릴 수 있습니다.
그러면 과연 이런 패스 생성이 어디에 쓰일 수 있을까요?
다음 글에서 가상의 파생상품을 하나 도입하여 그 가격을 도출할 때 Brownian Bridge가 어떻게 쓰이는지 알아보겠습니다.
'금융공학' 카테고리의 다른 글
기초자산 변동성: 역사적 변동성#1 (0) | 2022.11.30 |
---|---|
Brownian Bridge를 이용한 금융상품의 계산 (0) | 2022.11.28 |
Brownian bridge: 1년뒤 주가타겟을 정조준하는 일일주가의 움직임을 모델링하자 #2 (0) | 2022.11.24 |
Brownian bridge: 1년뒤 주가타겟을 정조준하는 일일주가의 움직임을 모델링하자 #1 (0) | 2022.11.24 |
키움 ELS 1호의 만기근처 평가가격의 변화 (0) | 2022.11.21 |
댓글