작성자: admin 작성일시: 2016-07-21 17:06:10 조회수: 245 다운로드: 22
카테고리: 금융 공학 태그목록:

블랙-숄즈-머튼 모형과 몬테카를로 시뮬레이션을 이용한 옵션 가치 계산

다음은 유러피안 콜 옵션에 대해 블랙-숄즈-머튼 모형에 따른 주가 모형을 기반으로 몬테카를로 시뮬레이션 방식의 옵션 가치를 계산하는 함수이다.

블랙-숄즈-머튼 모형에 따른 주가 모형은 위험 중립 측도하에서 다음 방정식을 따른다.

$$ dS_t = S_t \left( r_t \,dt + \sigma \,dW_t \right) $$

이를 오일러 이산화를 하면 다음과 같아진다.

$$ S_{t + \Delta t} = S_t \exp \left( (r_t - 0.5\sigma^2) \,\Delta t + \sigma \sqrt{\Delta t} \,Z \right) $$
In [1]:
def bsm_mcs_valuation(strike):
    ''' 유러피안 콜 옵션의 블랙-숄즈-머튼 모형 몬테카를로 계산기
    
    인수
    ==========
    strike : float
        옵션의 행사가
    
    반환값
    =======
    value : float
        콜 옵션의 현재 가치의 추정치
    '''
    import numpy as np
    S0 = 100.; T = 1.0; r = 0.05; vola = 0.2
    M = 50; I = 20000
    dt = T / M
    rand = np.random.standard_normal((M + 1, I))
    S = np.zeros((M + 1, I)); S[0] = S0
    for t in range(1, M + 1):
        S[t] = S[t-1] * np.exp((r - 0.5 * vola ** 2) * dt
                               + vola * np.sqrt(dt) * rand[t])
    value = (np.exp(-r * T)
                     * np.sum(np.maximum(S[-1] - strike, 0)) / I)
    return value

순차 계산

In [2]:
def seq_value(n):
    ''' 옵션 가치의 순차 계산
    
    인수
    ==========
    n : int
        옵션 가치 및 행사가의 갯수
    '''
    strikes = np.linspace(80, 120, n)
    option_values = []
    for strike in strikes:
        option_values.append(bsm_mcs_valuation(strike))
    return strikes, option_values
In [3]:
n = 100  # 계산할 옵션의 수
%time strikes, option_values_seq = seq_value(n)
CPU times: user 10.7 s, sys: 278 ms, total: 11 s
Wall time: 11 s
In [4]:
plt.plot(strikes, option_values_seq, 'b')
plt.plot(strikes, option_values_seq, 'r.')
plt.grid(True)
plt.xlabel('strikes')
plt.ylabel('European call option values')
plt.show()

IPython.parallel 을 이용한 병렬 계산

In [5]:
from ipyparallel import Client
c = Client(profile="default")
view = c.load_balanced_view()
In [6]:
def par_value(n):
    ''' Sequential option valuation.
    
    Parameters
    ==========
    n : int
        number of option valuations/strikes
    '''
    strikes = np.linspace(80, 120, n)
    option_values = []
    for strike in strikes:
        value = view.apply_async(bsm_mcs_valuation, strike)
        option_values.append(value)
    c.wait(option_values)
    return strikes, option_values
In [7]:
%time strikes, option_values_obj = par_value(n)
CPU times: user 419 ms, sys: 58.6 ms, total: 477 ms
Wall time: 3.26 s
In [8]:
option_values_obj[0].metadata
Out[8]:
{'after': [],
 'completed': datetime.datetime(2016, 7, 21, 8, 53, 54, 865898),
 'data': {},
 'engine_id': 1,
 'engine_uuid': u'ff51bb80-6922-470e-a9ac-04e0e0fb3d66',
 'error': None,
 'execute_input': None,
 'execute_result': None,
 'follow': [],
 'msg_id': u'6b3c8407-2154-4589-9ce7-7855432435ee',
 'outputs': [],
 'received': datetime.datetime(2016, 7, 21, 8, 53, 54, 873224),
 'started': datetime.datetime(2016, 7, 21, 8, 53, 54, 619749),
 'status': u'ok',
 'stderr': '',
 'stdout': '',
 'submitted': datetime.datetime(2016, 7, 21, 8, 53, 54, 575964)}
In [9]:
option_values_obj[0].result()
Out[9]:
24.484997735594252
In [10]:
option_values_par = []
for res in option_values_obj:
    option_values_par.append(res.result())
In [11]:
plt.plot(strikes, option_values_seq, 'b', label='Sequential')
plt.plot(strikes, option_values_par, 'r.', label='Parallel')
plt.grid(True); plt.legend(loc=0)
plt.xlabel('strikes')
plt.ylabel('European call option values')
plt.show()

질문/덧글

아직 질문이나 덧글이 없습니다. 첫번째 글을 남겨주세요!