BAW模型
一、MATLAB代码
% Barone-Adesi and Whaley quadratic approximation to vanilla options
clc; clear;
% Input the option parameters
S = 90; % Spot Price
K = 100; % Strike Price
T = 0.5; % Maturity
r = 0.1; % Risk free rate
q = 0.1; % Dividend yield
v = 0.25; % Volatility
IsCall = 1; %
% Find the European and American prices, and the critical stock value S*
fprintf(' Spot Euror Amer Premium\n')
fprintf('--------------------------------------- \n')
%[Sx,EuroPrice,AmerPrice]
[Sx,EuroPrice,AmerPrice] = BAWPrice(S,K,r,q,v,T,IsCall);
fprintf('%8.4f %8.4f %8.4f %8.4f\n',...
Sx,EuroPrice,AmerPrice,AmerPrice-EuroPrice);
fprintf('--------------------------------------- \n')
function [Sx,EuroPrice,AmerPrice]= BAWPrice(S,K,r,q,sigma,T,IsCall)
% Barone-Adesi and Whaley Method for American options
% Finds the American prices as the European prices + premium
% Premium is based on Sx, the critical stock price
% S = Spot price
% K = Strike price
% r = Risk free rate
% q = Dividend yield
% v = Volatility
% T = Maturity
% PutCall = 'C'all or 'P'ut
% Functions for Black Scholes call and put
BSCall = @(s,K,r,q,sigma,T) s.*exp(-q.*T).*normcdf((log(s./K) + (r-q+sigma.^2./2).*T)./sigma./sqrt(T)) - K.*exp(-r.*T).*normcdf((log(s./K) + (r-q+sigma.^2./2).*T)./sigma./sqrt(T) - sigma.*sqrt(T));
BSPut = @(s,K,r,q,sigma,T) K.*exp(-r.*T).*normcdf(-(log(s./K) + (r-q+sigma.^2./2).*T)./sigma./sqrt(T) + sigma.*sqrt(T)) - s.*exp(-q.*T).*normcdf(-(log(s./K) + (r-q+sigma.^2./2).*T)./sigma./sqrt(T));
% Quadratic approximation
switch IsCall
case 1
EuroPrice = BSCall(S,K,r,q,sigma,T);
start = S;
[Sx,~] = fminsearch(@(s) findSx(s,K,r,q,sigma,T,IsCall), start);
d1 = (log(Sx/K) + (r-q+sigma^2/2))/sigma/sqrt(T);
n = 2*(r-q)/sigma^2;
k = 2*r/sigma^2/(1-exp(-r*T));
q2 = (1-n+sqrt((n-1)^2+4*k))/2;
A2 = Sx*(1-exp(-q*T)*normcdf(d1))/q2;
if SSx
AmerPrice = EuroPrice + A1*(S/Sx)^q1;
else
AmerPrice = K - S;
end
end
二、VBA代码
Public Function BWAmerican(S, k, T, R, q, Sigma As Double, IsCall As Boolean) As Double
'===========================================================
'BAW定价计算模块
'输入参数:
'——→ S:标的价
'——→ K:执行价
'——→ T:到期期限
'——→ r:无风险利率
'——→ q:红利率
'——→ Sigma:波动率
'——→ IsCall:是否看涨期权,输入True为看涨,输入False为看跌
'
'输出参数
'——→ BWAmerican:美式期权价格
'===========================================================
Dim dt As Double
Dim A1 As Double, a2 As Double, b As Double, A As Double
Dim h As Double, L1 As Double, L2 As Double
Dim D1 As Double, Sc As Double
b = 2 * (R - q) / Sigma ^ 2 - 1
A = 2 * R / Sigma ^ 2
h = 1 - Exp(-R * T)
L1 = (-b - Sqr(b ^ 2 + 4 * A / h)) / 2
L2 = (-b + Sqr(b ^ 2 + 4 * A / h)) / 2
dt = Sigma * Sqr(T)
Select Case IsCall
Case True '//看涨
If q = 0 Then
BWAmerican = BSprice(S, k, T, R, q, Sigma, True)
Else
Sc = Bisectional_call(S, k, T, R, q, Sigma)
D1 = (Log(Sc / k) + (R - q + 0.5 * Sigma ^ 2) * T) / dt
a2 = (1 - Exp(-q * T) * Application.NormSDist(D1)) * (Sc / L2)
If S < Sc Then
BWAmerican = BSprice(S, k, T, R, q, Sigma, True) + a2 * (S / Sc) ^ L2
Else
BWAmerican = S - k
End If
End If
Case False '//看跌
Sc = Bisectional_put(S, k, T, R, q, Sigma)
D1 = (Log(Sc / k) + (R - q + Sigma ^ 2 / 2) * T) / dt
A1 = -(1 - Exp(-q * T) * Application.NormSDist(-D1)) * (Sc / L1)
If S > Sc Then
BWAmerican = BSprice(S, k, T, R, q, Sigma, False) + A1 * (S / Sc) ^ L1
Else
BWAmerican = k - S
End If
End Select
End Function
Private Function Bisectional_call(S, k, T, R, q, Sigma As Double) As Double
Dim n As Integer
Dim dt As Double
Dim Sx As Double, Su As Double, Sl As Double, Suu As Double
Dim D1 As Double, d2 As Double, L2 As Double
Dim err As Double, c1 As Double, c2 As Double
Dim b As Double, A As Double, h As Double
Dim N1 As Double, N2 As Double, E_st As Double
Dim IterationCountE As Double
dt = Sigma * Sqr(T)
D1 = (Log(S / k) + (R - q + Sigma ^ 2 / 2) * T) / dt
d2 = D1 - dt
N1 = Application.NormSDist(D1)
N2 = Application.NormSDist(d2)
E_st = S * Exp((R - q) * T) * N1 / N2
Su = E_st ' Guess the high bound
Sl = S ' Guess the low bound
Suu = Su
b = 2 * (R - q) / Sigma ^ 2 - 1
A = 2 * R / Sigma ^ 2
h = 1 - Exp(-R * T)
L2 = (-b + Sqr(b ^ 2 + 4 * A / h)) / 2
Start_Iteration:
IterationCountE = 0.000000001
While (Su - Sl) > IterationCountE
Sx = (Su + Sl) / 2
D1 = (Log(Sx / k) + (R - q + Sigma ^ 2 / 2) * T) / dt
c1 = Sx - k
c2 = BSprice(Sx, k, T, R, q, Sigma, True) + (1 - Exp(-q * T) * Application.NormSDist(D1)) * Sx / L2
If (c2 - c1) > 0 Then
Sl = Sx
Else
Su = Sx
End If
Wend
If (Round(Sx, 4) = Round(Suu, 4)) Then
Su = 2 * Suu
Suu = Su
GoTo Start_Iteration
End If
Bisectional_call = Sx
End Function
Private Function Bisectional_put(S, k, T, R, q, Sigma As Double) As Double
Dim n As Integer
Dim dt As Double
Dim Sx As Double, Su As Double, Sl As Double, Sll As Double
Dim D1 As Double, d2 As Double, L2 As Double
Dim err As Double, P1 As Double, P2 As Double
Dim b As Double, A As Double, h As Double
Dim NN1 As Double, NN2 As Double, E_st As Double
Dim L1 As Double, IterationCountE As Double
dt = Sigma * Sqr(T)
D1 = (Log(S / k) + (R - q + Sigma ^ 2 / 2) * T) / dt
d2 = D1 - dt
NN1 = Application.NormSDist(-D1)
NN2 = Application.NormSDist(-d2)
E_st = S * Exp((R - q) * T) * NN1 / NN2
Sl = 0 ' Guess the low bound
Su = S ' Guess the high bound
Sll = Sl
b = 2 * (R - q) / Sigma ^ 2
A = 2 * R / Sigma ^ 2
h = 1 - Exp(-R * T)
L1 = (-(b - 1) - Sqr((b - 1) ^ 2 + 4 * A / h)) / 2
Start_Iteration:
IterationCountE = 0.000000001
While (Su - Sl) > IterationCountE
Sx = (Su + Sl) / 2
D1 = (Log(Sx / k) + ((R - q) + Sigma ^ 2 / 2) * T) / dt
P1 = k - Sx
P2 = BSprice(Sx, k, T, R, q, Sigma, False) - (1 - Exp(-q * T) * Application.NormSDist(-D1)) * Sx / L1
If (P2 - P1) > 0 Then
Su = Sx
Else
Sl = Sx
End If
Wend
Bisectional_put = Sx
End Function
Public Function BSprice(S, k, T, R, q, Sigma As Double, IsCall As Boolean)
'===========================================================
'BS定价计算模块
'输入参数:
'——→ S:标的价
'——→ K:执行价
'——→ T:到期期限
'——→ r:无风险利率
'——→ q:红利率
'——→ Sigma:波动率
'——→ IsCall:是否看涨期权,输入True为看涨,输入False为看跌
'
'输出参数
'——→ BSprice:欧式期权价格
'===========================================================
Dim D1, d2, Price As Double
D1 = (Log(S / k) + (R - q + Sigma ^ 2 / 2) * T) / (Sigma * Sqr(T))
d2 = D1 - Sigma * Sqr(T)
If IsCall Then
Price = S * Exp(-q * (T)) * Application.WorksheetFunction.Norm_S_Dist(D1, True) - k * Exp(-R * (T)) * Application.WorksheetFunction.Norm_S_Dist(d2, True)
Else
Price = k * Exp(-R * (T)) * Application.WorksheetFunction.Norm_S_Dist(-d2, True) - S * Exp(-q * (T)) * Application.WorksheetFunction.Norm_S_Dist(-D1, True)
End If
BSprice = Price
End Function
|
|