Nel modello di Black e Scholes, che si presta per la sua semplicità, il prezzo di un’opazione di acquisto si ricava in forma chiusa.
Dato un processo stocastico per il sottostante
\[\frac{dS(t)}{S(t)}=\mu dt + \sigma dW(t),\]
con un tasso di interesse privo di rischio costante \(r\), il prezzo di un’opzione di acquisto:
\[C(t)=\mathbb{E}_{t}^{\mathbb{Q}}\left[\left(S\left(T\right)-K\right)\mathbb{I}_{S\left(T\right)>K}\frac{G\left(t\right)}{G\left(T\right)}\right],\]
si ottiene in forma chiusa come
\[C\left(t\right)=S\left(t\right)\int_{-\infty}^{d_{1}}\frac{1}{\sqrt{2\pi}}e^{-\frac{1}{2}x^{2}}dx-KB\left(t,T\right)\int_{-\infty}^{d_{2}}\frac{1}{\sqrt{2\pi}}e^{-\frac{1}{2}x^{2}}dx,\]
dove:
\[d_{1}=\frac{\ln\frac{S\left(t\right)}{K}+\left(r+\frac{1}{2}\sigma^{2}\right)\left(T-t\right)}{\sigma\sqrt{T-t}},\]
\[d_{2}=\frac{\ln\frac{S\left(t\right)}{K}+\left(r-\frac{1}{2}\sigma^{2}\right)\left(T-t\right)}{\sigma\sqrt{T-t}}.\]
In R calcoliamo il valore di un’opzione mediante i seguenti comandi.
# Parametri del modello
S0=25 #prezzo iniziale
r=0.04
sigma=0.2
K=30 #prezzo di esercizio
T=3 #tempo a scadenza
# Formula di Black e Scholes
BS=S0*pnorm((log(S0/K)+(r+0.5*sigma^2)*T)/(sigma*sqrt(T)))-
K*exp(-r*T)*pnorm((log(S0/K)+(r-0.5*sigma^2)*T)/(sigma*sqrt(T)))
BS
## [1] 2.801144
Il prezzo dell’opzione si può ricavare anche mediante simulazione Monte-Carlo. Possiamo scrivere una funzione che crea \(N\) percorsi simulati e, poi, calcola il valore dell’opzione come media (valore atteso) dei payoff dell’opzione alla fine dei percorsi.
# Parametri della simulazione
dt=1/250 #dati giornalieri
N=1000 #numero di percorsi simulati
# Funzione Monte-Carlo
# Simulazioni Monte-Carlo
MC=function(N){
S=array(NA,dim=c(T/dt,N))
dW=array(rnorm(T/dt*N,0,sqrt(dt)),dim=c(T/dt,N))
S[1,]=S0
for (i in 2:(T/dt)){
S[i,]=S[i-1,]+S[i-1,]*r*dt+S[i-1,]*sigma*dW[i-1,]
}
mean((tail(S,1)-K)*as.numeric(tail(S,1)>K)*exp(-r*T))
}
In questo codice la funzione tail prende l’ultimo valore
delle simulazioni (cioè, nel modello teorico, \(S(T)\)) e la funzione
as.numeric trasforma un valore VERO o FALSO,
rispettivamente, in \(1\) o \(0\).
Il valore dell’opzione, come output della funzione Monte-Carlo, è molto variabile. Ne vediamo alcuni:
MC(1000)
## [1] 2.862749
MC(1000)
## [1] 2.794535
MC(1000)
## [1] 2.838625
Proviamo a creare \(100\) valori ottenuti con questo metodo e a confrontarne la distribuzione con il “vero” valore di Black e Scholes.
M=100
Call=array(NA,100)
for (i in 1:M){
Call[i]=MC(1000)
}
hist(Call,xlab='Prezzo')
abline(v=c(BS,mean(Call)),lwd=2,lty=2,
col=c('blue','red'))
Il metodo delle variabili antitetiche si basa sull’idea di generare due volte il processo di Wiener \(dW(t)\), aggiungendo, alla simulazione originale, il valore \(-dW(t)\). Poiché il processo di Wiener è distribuito normalmente con media nulla, il suo opposto è distribuito esattamente nello stesso modo. Tuttavia, le due variabili \(dW(t)\) e \(-dW(t)\) hanno correlazione negativa perfetta e, quindi, generarno una varianza complessiva più bassa di quella originale.
Questo metodo, dunque, mira a ridurre la variabilità delle simulazioni generando due variabili artificalmente correlate negativamente.
Scriviamo una seconda funzione che utilizzi queste due variabili generando due matrici di simulazioni del prezzo \(S(t)\).
# Metodo delle variabili antitetiche
MC2=function(N){
S1=S2=array(NA,dim=c(T/dt,N))
dW=array(rnorm(T/dt*N,0,sqrt(dt)),dim=c(T/dt,N))
S1[1,]=S2[1,]=S0
for (i in 2:(T/dt)){
S1[i,]=S1[i-1,]+S1[i-1,]*r*dt+S1[i-1,]*sigma*dW[i-1,]
S2[i,]=S2[i-1,]+S2[i-1,]*r*dt+S2[i-1,]*sigma*(-dW[i-1,])
}
mean(c((tail(S1,1)-K)*as.numeric(tail(S1,1)>K)*exp(-r*T),
(tail(S2,1)-K)*as.numeric(tail(S2,1)>K)*exp(-r*T)))
}
Possiamo così generare una serie di simulazioni con la nuova funzione e metterle a confronto con le simulazioni precedenti.
# Ripetizione del metodo
M=100
Call2=array(NA,M)
for (i in 1:M){
Call2[i]=MC2(1000)
}
Per confrontare i due metodi sovrapponiamo gli istogrammi.
# Confronto degli istogrammi
asse=seq(min(Call,Call2),max(Call,Call2),length.out=20)
hist(Call2,asse,col=rgb(0,1,0,0.2))
hist(Call,asse,col=rgb(1,0,0,0.2),add=T)
abline(v=c(mean(Call),mean(Call2),BS),
col=c('red','darkgreen','blue'),
lwd=2,lty=2)
Vediamo, così, che le simulazioni con le variabili antitetiche (verdi) sono meno variabili e, quindi, danno una distribuzione più concentrata sul valore medio.
Vediamo, anche, che la media della simulazione verde è più vicina al valore “vero” rispetto alla media delle simulazioni iniziali (rosse).
Questo metodo può essere utilizzato per calcolare in modo più efficienti i valori attesi, ma non per fare simulazioni di scenari. Il metodo, infatti, riduce artificialmente la varianza.