You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Introduzione alla Programmazione e Applicazioni per la<br />
Finanza M2 (Prodotti Derivati)<br />
<strong>Lezione</strong> <strong>12</strong><br />
Anno accademico 2005-06<br />
Titolare corso: Prof. Costanza Torricelli<br />
Docente a contratto: Dott. Marianna Brunetti<br />
Il pricing delle opzioni in VBA
Il pricing delle opzioni in VBA<br />
In particolare implementeremo:<br />
1. Binomiale<br />
Sub<br />
Fun<br />
Fun<br />
Sub<br />
a. per opzioni europee<br />
b. per opzioni europee, sotto l’ipotesi che<br />
c. per opzioni americane<br />
2. B&S<br />
a. per call e put<br />
S ~ logN<br />
Sub<br />
Fun<br />
b. per call e put con l’ausilio di Inputbox e Msgbox<br />
c. per il calcolo della volatilità implicita<br />
Il pricing delle opzioni in VBA
C<br />
=<br />
n<br />
∑<br />
i = 0<br />
1a) Il Binomiale per opzioni Europee<br />
⎛<br />
⎜<br />
⎝<br />
n<br />
i<br />
⎞<br />
⎟<br />
⎠<br />
q<br />
i<br />
u<br />
q<br />
n − i<br />
d<br />
Max<br />
(<br />
i<br />
n −i<br />
S ( 1 + u ) ( 1 + d ) − X ; 0)<br />
P<br />
n<br />
= ∑<br />
i = 0<br />
⎛<br />
⎜<br />
⎝<br />
n<br />
i<br />
⎞<br />
⎟<br />
⎠<br />
q<br />
i<br />
u<br />
q<br />
n−<br />
i<br />
d<br />
Max<br />
(<br />
i<br />
n−<br />
i<br />
X − S( 1 + u ) ( 1 + d ) ; 0)<br />
Sub PrezziBinomiali ()<br />
Dim S, X, r, u, d As Double<br />
Dim n As Integer<br />
S = 50, X = 50, r = 0.06, u = 0.1, d = -0.03, n = 2<br />
Dim q_up, q_down, C, P As Double<br />
Dim i As Integer<br />
q_up = (r - d) / ((1 + r) * (u - d))<br />
q_down = (u - r) / ((1 + r) * (u - d))<br />
(segue)<br />
Il pricing delle opzioni in VBA
1a) Il Binomiale per opzioni Europee (2)<br />
(segue)<br />
C = 0<br />
For i = 0 To n<br />
C = C + Application.WorksheetFunction.Combin(n, i) * q_up ^ i * q_down ^ (n - i) * _<br />
Application.WorksheetFunction.Max(S * (1 + u) ^ (i) * (1 + d) ^ (n - i) - X, 0)<br />
Next i<br />
P = 0<br />
For i = 0 To n<br />
P = P + Application.WorksheetFunction.Combin(n, i) *q_up ^ i * q_down ^ (n - i) * _<br />
Application.WorksheetFunction.Max(X - S * (1 + u) ^ (i) * (1 + d) ^ (n - i), 0)<br />
Next i<br />
End Sub<br />
RICORDA: usiamo Application.WorksheetFunction.Qualcosa (o anche solo<br />
Application.Qualcosa) per richiamare in VBA la funzione Qualcosa di Excel<br />
Il pricing delle opzioni in VBA
1b) Il Binomiale per opzioni Europee, con S ~ logN<br />
Faremo approssimazioni tali che i movimenti “up” e “down” di S convergano<br />
ad una log-Normale:<br />
1.<br />
2.<br />
T<br />
∆t =<br />
n<br />
r<br />
R = e<br />
∆t<br />
3.<br />
u<br />
e<br />
∆t<br />
4.<br />
5.<br />
6.<br />
= σ t<br />
up = 1 + u<br />
−σ<br />
∆<br />
d = e<br />
down = 1 + d<br />
R − down<br />
q u =<br />
R *(<br />
up − down)<br />
up − R<br />
q d =<br />
R *(<br />
up − down)<br />
Il pricing delle opzioni in VBA
1b) Il Binomiale per call Europee, con S ~ logN<br />
Function EuroCall(S, X, T, rf, sigma, n)<br />
delta_t = T / n<br />
up = Exp(sigma * Sqr(delta_t))<br />
down = Exp(-sigma * Sqr(delta_t))<br />
r = Exp(rf * delta_t)<br />
q_up = (r - down) / (r * (up - down))<br />
q_down = (up - r) / (r * (up - down))<br />
EuroCall = 0<br />
For i = 0 To n<br />
EuroCall = EuroCall + Application.Combin(n, i) * q_up ^ i * q_down ^ (n - i) * _<br />
Application.Max(S * up ^ i * down ^ (n - i) - X, 0)<br />
Next i<br />
End Function<br />
Il pricing delle opzioni in VBA
1b) Il Binomiale per put Europee, con S ~ logN<br />
Function EuroPut(S, X, T, rf, sigma, n)<br />
delta_t = T / n<br />
up = Exp(sigma * Sqr(delta_t))<br />
down = Exp(-sigma * Sqr(delta_t))<br />
r = Exp(rf * delta_t)<br />
q_up = (r - down) / (r * (up - down))<br />
q_down = 1 / r - q_up<br />
EuroPut = 0<br />
For i = 0 To n<br />
EuroPut = EuroPut + Application.WorksheetFunction.combin(n, i) * _<br />
q_up ^ i * q_down ^ (n - i) * _<br />
Application.WorksheetFunction.Max(X - S * up ^ i * down ^ (n - i), 0)<br />
Next i<br />
End Function<br />
Il pricing delle opzioni in VBA
Gli Array<br />
Ad 1 dimensione (“vettore”)<br />
“serie di elementi omogenei<br />
individuati da un indice”<br />
Sintassi ed assegnazione<br />
Dim NomeVettore (i) [As Tipo]<br />
A 2 dimensioni (“matrice”)<br />
“tabella di elementi omogenei<br />
individuati da una coppia di indici,<br />
uno per riga ed uno per colonna”<br />
Dim NomeMatrice (i, j) [As Tipo]<br />
Dim Vettore (3) As Double<br />
Dim Matrice (3,3) As Double<br />
• La sintassi completa per quanto riguarda gli indici è ([min to] max)<br />
Dim Vettore2 (1 to 3) As Double<br />
Dim Matrice2 (1 to 3, 1 to 3) As Double<br />
• Option Base 0 => se dichiaro indice i, il numero degli elementi è (i +1)<br />
• Option Base 1 => dichiarando i, il numero degli elementi è effettivamente i<br />
• Assegnazione avviene sempre con l’ = è Vettore(i) = 3<br />
Il pricing delle opzioni in VBA
Gli Array (2)<br />
‣ Statici = il numero di elementi rimane costante in tutta la procedura.<br />
‣ Dinamici = utili quando non sappiamo a priori il numero di elementi<br />
è ridimensioniamo con il comando ReDim<br />
Esempi<br />
Sub provaArray()<br />
Dim vettore() As Double<br />
n = InputBox("inserire il numero di elementi")<br />
ReDim vettore(n) As Double<br />
End Sub<br />
Sub provaArray2()<br />
Dim Matrice() As Double<br />
i = InputBox("inserire il numero di righe della matrice")<br />
j = InputBox("inserire il numero di colonne della matrice")<br />
ReDim Matrice(i, j) As Double<br />
End Sub<br />
Il pricing delle opzioni in VBA
1c) Il Binomiale per opzioni call Americane<br />
‣ Modifichiamo le funzioni viste prima per il pricing delle opzioni europee in<br />
modo da tener conto dell’eventuale convenienza dell’esercizio anticipato in<br />
ciascun nodo intermedio dell’albero<br />
‣La prima parte della funzione è uguale…<br />
Function AmericanCall(S, X, T, rf, sigma, n)<br />
Dim delta_t, up, down, r, q_up, q_down As Double<br />
Dim State, Index As Integer<br />
delta_t = T / n<br />
up = Exp(sigma * Sqr(delta_t))<br />
down = Exp(-sigma * Sqr(delta_t))<br />
r = Exp(rf * delta_t)<br />
q_up = (r - down) / (r * (up - down))<br />
q_down = (up - r) / (r * (up - down))<br />
(segue)<br />
Il pricing delle opzioni in VBA
1c) Il Binomiale per opzioni call Americane (2)<br />
‣ Nella seconda parte della funzione creiamo due vettori:<br />
•OptionReturnEnd è valori opzione in ciascuno stato del mondo in t+1<br />
•OptionReturnMiddle è valori opzione in ciascuno stato del mondo in t<br />
‣ ...che ridimensioniamo una volta noto il numero dei passi complessivi (n)<br />
Dim OptionReturnEnd() As Double<br />
Dim OptionReturnMiddle() As Double<br />
ReDim OptionReturnEnd(n + 1)<br />
(segue)<br />
‣ ora possiamo valutare l’opzione in ciascun possibile stato del mondo a<br />
scadenza calcolandone semplicemente il payoff<br />
For State = 0 To n<br />
OptionReturnEnd(State) = Application.Max(S * (up ^ State) * down ^ (n - State) - X, 0)<br />
Next State<br />
Il pricing delle opzioni in VBA<br />
(segue)
1c) Il Binomiale per opzioni call Americane (3)<br />
‣ per ciascun istante di tempo intermedio tra la scadenza e oggi (ovvero<br />
tra n-1 e 0), ridimensioniamo il vettore che contiene i valori dell'opzione<br />
nei nodi intermedi<br />
For Index = n - 1 To 0 Step -1<br />
ReDim OptionReturnMiddle(Index)<br />
(segue)<br />
‣ utilizzando un ciclo For, riempiamo ciascun elemento di questo vettore con<br />
il massimo tra il payoff dell’opzione in quel nodo e la valutazione dell'opzione<br />
con i prezzi nei vari stati del mondo<br />
For State = 0 To Index<br />
OptionReturnMiddle(State) = Application.Max(S * up ^ State * down ^ (Index - State) - X, _<br />
q_down * OptionReturnEnd(State) + q_up * OptionReturnEnd(State + 1))<br />
Next State<br />
Il pricing delle opzioni in VBA<br />
(segue)
1c) Il Binomiale per opzioni call Americane (4)<br />
‣ trovato il valore dell’opzione in ogni State (stato del mondo) di<br />
quell’Index (tempo), chiamo il vettore di valori appena trovato<br />
OptionReturnEnd, poiché la valutazione nei nodi precedenti sarà basata su<br />
questo (questo stesso vettore passa da OptionReturnMiddle a<br />
OptionReturnEnd!) è Ridimensiono e assegno stessi valori:<br />
ReDim OptionReturnEnd(Index)<br />
For State = 0 To Index<br />
OptionReturnEnd(State) = OptionReturnMiddle(State)<br />
Next State<br />
Next Index<br />
‣ Il ciclo ripete questa valutazione backward fino all’istante 0. Il prezzo<br />
dell’opzione è quindi dato da:<br />
AmericanCall = OptionReturnMiddle(0)<br />
End Function<br />
Il pricing delle opzioni in VBA<br />
(segue)
1c) Il Binomiale per opzioni put Americane<br />
Function AmericanPut(S, X, T, rf, sigma, n)<br />
Dim delta_t, up, down, r, q_up, q_down As Double<br />
Dim State, Index As Integer<br />
delta_t = T / n<br />
up = Exp(sigma * Sqr(delta_t))<br />
down = Exp(-sigma * Sqr(delta_t))<br />
r = Exp(rf * delta_t)<br />
q_up = (r - down) / (r * (up - down))<br />
q_down = (up - r) / (r * (up - down))<br />
Dim OptionReturnEnd() As Double<br />
Dim OptionReturnMiddle() As Double<br />
ReDim OptionReturnEnd(n + 1)<br />
For State = 0 To n<br />
OptionReturnEnd(State) = Application.Max(X - S * up ^ State * down ^ (n - State), 0)<br />
Next State<br />
Il pricing delle opzioni in VBA<br />
(segue)
1c) Il Binomiale per opzioni put Americane (2)<br />
(segue)<br />
For Index = n - 1 To 0 Step -1<br />
ReDim OptionReturnMiddle(Index)<br />
For State = 0 To Index<br />
OptionReturnMiddle(State) = Application.Max(X - S * up ^ State * down ^ (Index - State), _<br />
q_down * OptionReturnEnd(State) + q_up * OptionReturnEnd(State + 1))<br />
Next State<br />
ReDim OptionReturnEnd(Index)<br />
For State = 0 To Index<br />
OptionReturnEnd(State) = OptionReturnMiddle(State)<br />
Next State<br />
Next Index<br />
End Function<br />
AmericanPut = OptionReturnMiddle(0)<br />
Il pricing delle opzioni in VBA
2a) B&S per opzioni Europee<br />
Sub PrezzoCall()<br />
Dim S, X, r, T, sigma, D1, D2, ND1, ND2, MenoND1, MenoND2, C, P As Double<br />
S = 25<br />
X = 25<br />
r = 0.06<br />
T = 0.5<br />
sigma = 0.3<br />
D1 = (Log(S / X) + (r + 0.5 * (sigma ^ 2)) * T) / (sigma * Sqr(T))<br />
D2 = D1 - Sqr(T) * sigma<br />
ND1 = Application.NormSDist(D1)<br />
ND2 = Application.NormSDist(D2)<br />
MenoND1 = Application.NormSDist(-D1)<br />
MenoND2 = Application.NormSDist(-D2)<br />
C = S * ND1 - (X * Exp(-r * T) * ND2)<br />
P = (X * Exp(-r * T) * (MenoND2)) - (S * (MenoND1))<br />
End Sub<br />
Il pricing delle opzioni in VBA
2b) B&S per opzioni Europee – InputBox e MsgBox<br />
Sub PrezzoCallePutBlackAndSholes()<br />
Dim CalcoloD1, CalcoloD2, NormalD1, NormalD2, C, P As Double<br />
Dim S As Double<br />
S = InputBox("Immettere il prezzo del Sottostante", "Calcolo prezzo B&S")<br />
Dim X As Double<br />
X = InputBox("Immettere lo Strike della Call", "Calcolo prezzo B&S")<br />
Dim r As Double<br />
r = InputBox("Immettere il tasso risk-free", "Calcolo prezzo B&S")<br />
Dim T As Double<br />
T = InputBox("Immettere la scandenza della call", "Calcolo prezzo B&S")<br />
Dim sigma As Double<br />
sigma = InputBox("Immettere la varianza del sottostante", "Calcolo prezzo B&S")<br />
CalcoloD1 = (Log(S / X) + (r + 0.5 * (sigma ^ 2)) * T) / (sigma * Sqr(T))<br />
CalcoloD2 = CalcoloD1 - (Sqr(T) * sigma)<br />
NormalD1 = Application.NormSDist(CalcoloD1)<br />
NormalD2 = Application.NormSDist(CalcoloD2)<br />
C = S * NormalD1 - (X * Exp(-r * T) * NormalD2)<br />
P = C + (X * Exp(-r * T)) - S<br />
MsgBox "Il prezzo della Call è " & Str(Round(C, 3)), , "Calcolo prezzo Call"<br />
MsgBox "Il prezzo della corrispondente Put è " & Str(Round(P, 3)), , "Calcolo Prezzo Put"<br />
End Sub<br />
Il pricing delle opzioni in VBA
2c) B&S per il calcolo della Volatilità Implicita<br />
Function VolatilityCall(S, X, T, r, C)<br />
Dim High, Low, CalcoloD1, CalcoloD2, NormalD1, NormalD2, PrezzoCall As Double<br />
High = 1<br />
Low = 0<br />
Do While (High - Low) > 0.00001<br />
CalcoloD1 = (Log(S / X) + (r + 0.5 * (((High + Low) / 2) ^ 2)) * T) / (((High + Low) / 2) * Sqr(T))<br />
CalcoloD2 = CalcoloD1 - Sqr(T) * ((High + Low) / 2)<br />
NormalD1 = Application.NormSDist(CalcoloD1)<br />
NormalD2 = Application.NormSDist(CalcoloD2)<br />
PrezzoCall = S * NormalD1 - (X * Exp(-r * T) * NormalD2)<br />
If PrezzoCall > C Then<br />
High = (High + Low) / 2<br />
Else:<br />
Low = (High + Low) / 2<br />
End If<br />
Loop<br />
VolatilityCall = (High + Low) / 2<br />
End Function<br />
Il pricing delle opzioni in VBA