Mô hình Python 76 màu đen

Mô hình định giá Black-Scholes (BS) vẫn là một phương pháp định giá quyền chọn tài chính tiêu chuẩn trên thực tế

Mặc dù đã có nhiều nghiên cứu về các mô hình được cải thiện và có thể thực tế hơn, nhưng thực tế là mô hình BS được giả định hoàn toàn theo cách mà hầu hết các mức giá quyền chọn được niêm yết trong thực tế, xét về tham số mô hình được gọi là độ biến động ngụ ý. Bất kỳ ai làm việc với quyền chọn trong ngành tài chính sẽ phải biết những kiến ​​thức cơ bản về phương pháp định giá này. Trong hướng dẫn này, chúng tôi sẽ hướng dẫn bạn lượng lý thuyết tối thiểu cần thiết để triển khai phương pháp định giá trong Python và sau đó xem xét một ví dụ tính toán cơ bản

Khi bạn xem qua bài viết, vui lòng xem video giải thích liên quan

Mô hình Black-Scholes của Python và Khái niệm cơ bản về định giá quyền chọn

Mô hình Python 76 màu đen

Xem video này trên YouTube

Mô hình Black-Scholes

Gọi St là giá cổ phiếu tại thời điểm t. Mô hình Black-Scholes dựa trên mô hình Geometric Brownian Motion (GBM) ngụ ý rằng suất sinh lợi logarit của giá cổ phiếu có thể được mô tả bằng phân phối chuẩn có phương sai tỷ lệ với bước thời gian.

Mô hình Python 76 màu đen

Đây cũng là một phần trong định nghĩa của GBM rằng các nhật ký trả về này độc lập về mặt thống kê khi được đo trong các khoảng thời gian khác nhau. Chúng tôi giả định rằng thời gian t được đo bằng năm, trong khi St được đo bằng đơn vị tiền tệ mà giá cổ phiếu được xác định, chẳng hạn như USD hoặc EUR. μ được gọi là lợi tức kỳ vọng và σ là độ biến động. Bây giờ, hãy giả sử rằng giá ban đầu S0 = 1 và giả sử lợi nhuận kỳ vọng là 5% và độ biến động là 20%, nói cách khác, μ = 0. 05  và σ = 0. 2

Lý do của thuật ngữ

Mô hình Python 76 màu đen

trong biểu thức cho tham số vị trí của phân phối chuẩn là độ lồi của hàm mũ đưa ra một sai lệch phải được bù cho;

Phân phối của giá cổ phiếu trong tương lai một năm kể từ bây giờ, với điều kiện giá hiện tại bằng 1, được gọi là phân phối logic chuẩn và có thể được vẽ trong Python bằng cách sử dụng mô-đun con

import numpy as np
import matplotlib.pyplot as plt

Nsim = 30
t0 = 0
t1 = 1
Nt = 100

mu=0.05
sigma=0.2
S0 = 1

t = np.linspace(t0,t1,Nt)
dt = (t1-t0)/Nt

S = np.zeros([Nsim,Nt])
S[:,0] = S0
for j in range(0, Nt-1):
    S[:,j+1] = S[:,j]*np.exp((mu-sigma**2/2)*dt + sigma*np.sqrt(dt)*np.random.normal(0,1, Nsim))

for j in range(0,Nsim):
    plt.plot(t,S[j,:])
plt.show()
0 và gói
import numpy as np
import matplotlib.pyplot as plt

Nsim = 30
t0 = 0
t1 = 1
Nt = 100

mu=0.05
sigma=0.2
S0 = 1

t = np.linspace(t0,t1,Nt)
dt = (t1-t0)/Nt

S = np.zeros([Nsim,Nt])
S[:,0] = S0
for j in range(0, Nt-1):
    S[:,j+1] = S[:,j]*np.exp((mu-sigma**2/2)*dt + sigma*np.sqrt(dt)*np.random.normal(0,1, Nsim))

for j in range(0,Nsim):
    plt.plot(t,S[j,:])
plt.show()
1 để tạo biểu đồ thực tế

from scipy.stats import lognorm
import matplotlib.pyplot as plt
import numpy as np
import math

mu = 0.05
sigma = 0.2
S0 = 1

x = np.linspace(0,2,1000)
y = lognorm.pdf(x, sigma,0,math.exp(mu))

plt.plot(x,y)
plt.show()

Mô hình Python 76 màu đen

Chúng ta có thể thấy rằng kết quả có khả năng xảy ra nhất, hay còn gọi là “chế độ” hoặc cực đại của hàm mật độ, nằm hơi lệch về bên trái của 1, tương ứng với thực tế toán học là chế độ của phân bố logic chuẩn tắc có thể được biểu diễn trong trường hợp này bằng

Mô hình Python 76 màu đen

Điều này có thể khiến một số người thất vọng vì lợi nhuận kỳ vọng được cho là 5%, tuy nhiên, phân phối bị sai lệch và do đó chế độ thực sự không bằng với giá trị trung bình

Mô hình Python 76 màu đen

Nói cách khác, kết quả rất có thể xảy ra là chúng tôi lỗ 1% cho khoản đầu tư, tuy nhiên, xác suất sai lệch về lợi nhuận dương lớn ngụ ý rằng trung bình chúng tôi vẫn sẽ kiếm được 5% tiền lãi

Nếu chúng ta muốn xem quá trình giá cổ phiếu này từ một góc độ khác, chúng ta có thể thực hiện mô phỏng đường dẫn, tôi. e. tạo ngẫu nhiên các quỹ đạo giả định của giá cổ phiếu theo luật xác suất của GBM. Chúng ta có thể làm điều này bằng Python chỉ bằng cách sử dụng gói

import numpy as np
import matplotlib.pyplot as plt

Nsim = 30
t0 = 0
t1 = 1
Nt = 100

mu=0.05
sigma=0.2
S0 = 1

t = np.linspace(t0,t1,Nt)
dt = (t1-t0)/Nt

S = np.zeros([Nsim,Nt])
S[:,0] = S0
for j in range(0, Nt-1):
    S[:,j+1] = S[:,j]*np.exp((mu-sigma**2/2)*dt + sigma*np.sqrt(dt)*np.random.normal(0,1, Nsim))

for j in range(0,Nsim):
    plt.plot(t,S[j,:])
plt.show()
0. Trong ví dụ bên dưới, chúng tôi đã mô phỏng 50 lần thực hiện lộ trình giá cổ phiếu trong hơn 1 năm, được chia thành 100 khoảng thời gian thống nhất

import numpy as np
import matplotlib.pyplot as plt

Nsim = 30
t0 = 0
t1 = 1
Nt = 100

mu=0.05
sigma=0.2
S0 = 1

t = np.linspace(t0,t1,Nt)
dt = (t1-t0)/Nt

S = np.zeros([Nsim,Nt])
S[:,0] = S0
for j in range(0, Nt-1):
    S[:,j+1] = S[:,j]*np.exp((mu-sigma**2/2)*dt + sigma*np.sqrt(dt)*np.random.normal(0,1, Nsim))

for j in range(0,Nsim):
    plt.plot(t,S[j,:])
plt.show()

Kết quả được hiển thị trong hình tiếp theo, nó có thể trông hơi giống biểu đồ giá cổ phiếu thực, ít nhất là nếu chúng ta bỏ qua thực tế là giá cổ phiếu thực đôi khi có những chuyển động tăng hoặc giảm rất đột ngột, do hậu quả của một số cuộc khủng hoảng hoặc nguyên nhân ngẫu nhiên khác.

Mô hình Python 76 màu đen

Bây giờ, hãy xem xét một quyền chọn mua kiểu Châu Âu đối với cổ phiếu được khởi tạo tại thời điểm t = 0, với số lượng danh nghĩa là 100 cổ phiếu, ngày hết hạn t = 1 và giá thực hiện $1. 1. Hợp đồng quyền chọn trao cho người nắm giữ quyền nhưng không bắt buộc phải mua 100 cổ phiếu vào ngày hết hạn một năm kể từ bây giờ, với giá mỗi cổ phiếu là 1 đô la và 10 xu. Thực tế là quyền chọn phải được thực hiện vào ngày hết hạn cụ thể là ý nghĩa của quyền chọn kiểu Châu Âu, cũng có những quyền chọn kiểu Mỹ có thể được thực hiện bất cứ lúc nào cho đến khi hết hạn và thậm chí có những loại khác có các quy ước khác nhau liên quan đến quyền chọn.

Lợi nhuận/lỗ thực hiện từ hợp đồng này là bao nhiêu, như là một chức năng của S1, giá cổ phiếu khi hết hạn? . 1, tất nhiên, tôi có thể ngay lập tức quay lại và bán lại cổ phiếu với giá cao hơn. Vì vậy, tiền chi trả sẽ là 100 * S1 – 1. 1. Tuy nhiên, nếu giá cổ phiếu giảm hoặc không tăng hơn 10%, giá trị bán lại của tôi sẽ không vượt quá số tiền tôi đã trả cho cổ phiếu, vì vậy tôi sẽ không quan tâm đến việc thực hiện quyền chọn. Tiền chi trả sau đó sẽ bằng không. Vì vậy, phần thưởng trong mọi trường hợp sẽ được đưa ra bởi biến ngẫu nhiên

Mô hình Python 76 màu đen

Chúng ta có thể vẽ đồ thị hàm này để hình dung sự phụ thuộc bất đối xứng của lợi nhuận vào kết quả cuối cùng của giá cổ phiếu

import numpy as np
import matplotlib.pyplot as plt

k = 1.1

def payoff(x):
    return 100*np.maximum(0,x-k)

x=np.linspace(0,2, 100)
y=payoff(x)

plt.plot(x,y)
plt.xlabel('Stock price at expiry')
plt.ylabel('Payoff')
plt.show()
Mô hình Python 76 màu đen

Thế giới không có rủi ro

Mô hình Black-Scholes ngụ ý rằng giá trị của một quyền chọn tại thời điểm trước khi hết hạn phải bằng với giá trị hiện tại dự kiến ​​của khoản hoàn trả trong tương lai, chỉ với một chút thay đổi. kỳ vọng không được tính bằng cách sử dụng phân phối xác suất thực tế của giá cổ phiếu, ngay cả khi chúng tôi thực sự tin vào các giả định thống kê của mô hình về thế giới. Thay vào đó, kỳ vọng nên được thực hiện theo phân phối xác suất trung tính với rủi ro, có nghĩa là lợi tức kỳ vọng μ được thay thế bằng lãi suất phi rủi ro r trong khi độ biến động không đổi. Lãi suất phi rủi ro là tỷ suất lợi nhuận mà một nhà đầu tư có thể mong đợi nhận được bằng cách cho vay tiền mà không phải chịu rủi ro vỡ nợ của người đi vay; . Trong thế giới trung lập với rủi ro tưởng tượng của chúng ta, lợi nhuận log sẽ có phân phối được đưa ra bởi

Mô hình Python 76 màu đen

Giá quyền chọn tại thời điểm 0 sau đó sẽ thu được bằng cách tính kỳ vọng

Mô hình Python 76 màu đen

trong đó EQ biểu thị kỳ vọng trung lập với rủi ro. Bây giờ, hãy thiết lập điều này trong Python và tính giá, chúng ta có thể sử dụng phép tích hợp Monte Carlo để tính toán kỳ vọng, nghĩa là chúng ta rút ra một số lượng lớn mẫu ngẫu nhiên từ phân phối xác suất này (tương ứng với giá trị cuối của các đường mô phỏng như . Theo quy luật số lượng lớn, ước tính này xấp xỉ kỳ vọng thực với độ chính xác tùy ý nếu chúng ta chỉ làm cho cỡ mẫu đủ lớn

import numpy as np
import math
Nsim = 10000
amount_underlying = 100
strike = 1.1
sigma = 0.2
mu = 0.06
r = 0.015


def payoff(x):
    return amount_underlying * np.maximum(0, x-strike)

num0 = np.random.normal(0,1,Nsim)

S0 = 15

S1 = np.exp(r-sigma**2/2+sigma*num0)

C0 = math.exp(-r)*np.mean(payoff(S1))

print(C0)

Bây giờ thực thi mã bằng Python, chúng tôi nhận được kết quả sau

D:\Finxter\Tutorials\Black-Scholes-1>python riskneutral.py
4.555089461101134

Điều này có ý nghĩa gì trong thực tế là với giá cổ phiếu là 1 đô la, mức độ biến động ngụ ý là 20% và lãi suất phi rủi ro là 1. 5%, chúng ta sẽ phải trả 4 đô la. 555 hôm nay (cộng thêm một số phí giao dịch) cho tùy chọn mua 100 cổ phiếu trong một năm với giá 1 đô la. 1 mỗi cổ phiếu

Tính toán chính xác thông qua Công thức Black-Scholes

Phương pháp tích phân Monte Carlo để đạt được kỳ vọng không có rủi ro của hàm hoàn trả chiết khấu là một phương pháp rất chung theo nghĩa là nó sẽ hoạt động cho tất cả các quyền chọn kiểu Châu Âu bất kể hàm hoàn trả nào mà chúng ta giả định, và thậm chí chúng ta có thể đã thử nghiệm với các phương pháp khác. . Tuy nhiên, trong thế giới logic chuẩn đơn giản hóa của mô hình BS, hóa ra thực sự có một phương trình dạng đóng mô tả giá quyền chọn mua, cái gọi là công thức Black-Scholes

Mô hình Python 76 màu đen

trong đó C0  là giá của quyền chọn khi bắt đầu hợp đồng, K là giá thực hiện, t là thời gian hết hạn, N  là hàm phân phối tích lũy của phân phối chuẩn chuẩn, trong khi d1 và d2 được cho bởi

Mô hình Python 76 màu đen

Mô hình Python 76 màu đen

Hãy cũng phiên âm các hàm này thành mã Python

import numpy as np
from scipy.stats import norm

amount_underlying = 100
strike = 1.1
sigma = 0.2
mu = 0.06
r = 0.015
S0 = 1
t = 1

def fun_d1(sigma,k,t,r,x):
    return (np.log(x/k) + (r+sigma**2/2)*t)/(sigma*np.sqrt(t))

def fun_d2(sigma,k,t,r,x):
    return fun_d1(sigma,k,t,r,x) - sigma*np.sqrt(t)

def call_value(amount_underlying, sigma,k,t,r,x):
    d1 = fun_d1(sigma,k,t,r,x)
    d2 = fun_d2(sigma,k,t,r,x)
    temp = norm.cdf(d1)*x-norm.cdf(d2)*k*np.exp(-r*t)
    return amount_underlying * temp
   
C0 = call_value(amount_underlying, sigma,strike,t,r,S0)

print(C0)

Bây giờ nếu chúng ta chạy cái này với Python, chúng ta sẽ nhận được kết quả như sau

D:\Finxter\Tutorials\Black-Scholes-1>python bsformula.py
4.775025500484964

So với kết quả Monte Carlo ở trên, chúng ta thấy rằng có sự khác biệt ở số thập phân thứ ba, 4. 775 so với 4. 777. Chúng tôi đã sử dụng 10000 mẫu cho mô phỏng của mình, hãy chạy lại với kích thước mẫu gấp 1000 lần, thay đổi tham số

import numpy as np
import matplotlib.pyplot as plt

Nsim = 30
t0 = 0
t1 = 1
Nt = 100

mu=0.05
sigma=0.2
S0 = 1

t = np.linspace(t0,t1,Nt)
dt = (t1-t0)/Nt

S = np.zeros([Nsim,Nt])
S[:,0] = S0
for j in range(0, Nt-1):
    S[:,j+1] = S[:,j]*np.exp((mu-sigma**2/2)*dt + sigma*np.sqrt(dt)*np.random.normal(0,1, Nsim))

for j in range(0,Nsim):
    plt.plot(t,S[j,:])
plt.show()
1 thành 10.000.000

D:\Finxter\Tutorials\Black-Scholes-1>python riskneutral.py
4.774596150369479

Bây giờ chúng ta đang tiến gần hơn đến tính toán dựa trên công thức, chỉ ra rằng hai phương pháp khác nhau thực sự tương đương nhau;