PROBLEMA 1

1a Scrivete una funzione in R che calcola il payout di una Call con posizione lunga.

La formula per il payoff di una call con posizione lunga è:

payoff_posizione_lunga <- function(ST, K){
  resCall <- pmax(ST-K,0)
  return(resCall)
}

I due parametri della funzione sono:

ST: il prezzo dell’asset sottostante

K: è il prezzo di strike

La funzione è definita attraverso un parallel max: se lo spot price è superiore allo strike price, il payoff è dato dalla differenza tra i due se invece lo spot price è inferiore o uguale allo strike price, il payoff è nullo.

1b Verificate il comportamento della funzione con un esempio numerico.

# Prezzo del titolo sottostante
ST <- 105
# Prezzo di strike
K <- 100
# Premio pagato per acquistare la call

# Calcola il payoff della call
cat("Il profitto è:",payoff_posizione_lunga(ST,K), "\n")
## Il profitto è: 5

In questo esempio, il prezzo del titolo sottostante è di 105, il prezzo di strike è di 100. La funzione restituisce un valore di 5, che è il payoff della call in base al prezzo attuale del titolo sottostante.

Ciò significa che il trader con una posizione lunga in questa call avrebbe un profitto di 5 se decidesse di esercitare la call e vendere il sottostante a 105.

2 Usando la funzione nel punto 1 disegnate il payoff di una strategia butterfy.

Per plottare il payoff di una strategia butterfly sono stati utilizzati i seguenti parametri:

  • prezzo corrente del titolo di 100

  • strike_price_1 pari a 95 per una posizione lunga

  • strike_price_2 pari a105 per un’altra posizione lunga

  • un prezzo di esercizio di 100 per le opzioni di vendita:

#parametri della strategia butterfly
stock_price <- seq(80, 120, by = 1)
strike_price_1 <- 95
strike_price_2 <- 105

# calcolo del payoff per ogni prezzo del titolo
payoff <- payoff_posizione_lunga(stock_price, strike_price_1) +
          payoff_posizione_lunga(stock_price, strike_price_2) -
          2 * payoff_posizione_lunga(stock_price, 100)

# plot del grafico del payoff
plot(stock_price, payoff, type = "l", xlab = "Prezzo del titolo sottostante", ylab = "Payoff", main = "Payoff della strategia butterfly")

Il grafico del payoff mostra un’area piatta tra i due strike price di acquisto (95 e 105) e due linee diagonalmente crescenti che si incontrano al prezzo di esercizio (100) delle opzioni di vendita.

La linea decrescente rappresenta il payoff dell’opzione call con strike price 105, mentre la linea crescente rappresenta il payoff dell’opzione call con strike price 95. Il guadagno massimo della strategia si verifica quando il prezzo del titolo sottostante si trova esattamente al prezzo di esercizio (100).

Il triangolo di payoff positivo compreso fra il primo e il secondo punto di strike, conferma l’efficacia dell’implementazione di questa strategia all’interno di un mercato stabile.

PROBLEMA 2

1) Scrivete una funzione in R che valuta un’opzione europea di tipo put in un albero binomiale uniperiodale.

-Gli argomenti della funzione sono: S0, K, t0 (valore di default 0), T (valoredi default 1) e r (regime composto);

-la funzione restituisce una lista contenente il prezzo della put a t0, il vettoreQ = (qu,qd) e la quantità y* di titolo rischioso nel portafoglio di replica.

BM_Put <- function(S0,u,d,K,FinalT=1, t0=0, r=0.02){
  Time2Mat <- FinalT-t0
  P<- matrix(c((1+r)^(Time2Mat),(1+r)^(Time2Mat), S0*u, S0*d),2,2) 
  InverseP <- solve(P)
  quantit <- InverseP %*% matrix(c(max(c(K-S0*u,0)), max(c(K-S0*d,0))),2,1)
  y <- quantit[2,1] # quantità di titolo rischioso
  qu <- ((1+r)^Time2Mat-d)/(u-d)
  qd <- 1-qu
  Q <- c(qu,qd)
  price <- 1/(1+r)^Time2Mat*(qu*max(c(K-S0*u,0))+(qd)*max(c(K-S0*d,0)))
  return(list(putprice=price, titolorischioso = y, Q=Q))
}

Questa funzione BM_Put valuta un’opzione Put europea in un albero binomiale uniperiodale.

Prende come input il prezzo iniziale dell’azione S0, i fattori di crescita u e di decrescita d, il prezzo di esercizio K, il tempo finale FinalT, il tempo iniziale t0 e il tasso di interesse privo di rischio r.

La funzione calcola il tempo alla scadenza Time2Mat, le probabilità neutre al rischio qu e qd e la quantità di titolo rischioso y nel portafoglio di replica.

L’output è una lista contenente price il prezzo della Put al tempo t0, la quantità di titolo rischioso y e le probabilità neutre al rischio Q.

Esempio:

# Definizione dei parametri
S0 <- 100
K <- 103
u <- 1.1
d <- 1/u
#Test della funzione

resBMP <- BM_Put(S0=S0, u=u, d=d, K=K)

# Stampa dei risultati
cat("Prezzo opzione put europea:",round(resBMP$putprice,2), "\n")
## Prezzo opzione put europea: 4.97
cat("Q:", round(resBMP$Q,2), "\n")
## Q: 0.58 0.42
cat("y_star:",round(resBMP$titolorischioso,2), "\n")
## y_star: -0.63

In questo esempio, la funzione BM_put viene utilizzata per valutare un’opzione Put europea con prezzo iniziale dell’azione S0 pari a 100, prezzo di esercizio K pari a 103, fattore di crescita u pari a 1.1 e fattore di decrescita d pari all’inverso di u.

In questo caso specifico, il prezzo della Put al tempo iniziale è pari a 4,97 , la quantità di titolo rischioso nel portafoglio replicante è pari a -0,63 e le probabilità neutre al rischio sono rispettivamente il 58% e 42%.

2) Scrivete una funzione in R che internamente richiama la funzione definita in precedenza e calcola il prezzo al tempo t0 di una call europea con la put-call parity.

La put-call parity permette di mettere in relazione i prezzi di un’opzione put e di una call, in particolare indica che la differenza di prezzo fra una call e una put è pari alla differenza tra il prezzo del sottostante S0 ed il valore del punto di strike K attualizzato.

Il prezzo della call sarà quindi pari alla somma del sottostante al tempo t0 e il prezzo della put, meno il valore attuale di K (calcolato con lo stesso regime composto precedente).

r <- 0.02
S0 <- 100
K <-103
Time2Mat <- 1 #uniperiodale

callprice <- S0 + resBMP$putprice - K*1/(1+r)^Time2Mat
 cat("Il prezzo dell'opzione Call è:",round(callprice,2), "\n")
## Il prezzo dell'opzione Call è: 3.99

In questo esempio, il prezzo del sottostante S0 è pari a 100, il prezzo dell’opzione Put resBMP$putprice è stato calcolato in precedenza utilizzando la funzione BM_Put, il prezzo di esercizio K è pari a 103, il tasso privo di rischio r è pari a 0.02 (2%) e il tempo alla scadenza Time2Mat è pari a 1.

Sostituendo questi valori nella condizione di put-call parity si ottiene il prezzo dell’opzione Call 3,99.

3) Verificare che la call precedente rispetti i vincoli di Merton.

Per una opzione call europea i vincoli di Merton implicano che il prezzo del sottostante sia maggiore del prezzo della call che a sua volta sarà maggiore del payoff calcolato attualizzando il punto di strike.

\(S_0 > \text{callprice} > \text{max} (S_0-K\frac{1}{(1+r)^{\text{Time2Mat}}},0)\)

Check_Merton<- function(S0, K, r, Time2Mat, callprice) {
  payoffattual <- pmax(S0 - K*1/(1+r)^Time2Mat, 0)
  if (S0 > callprice & callprice > payoffattual) {
    print("I vincoli di Merton sono soddisfatti")
  } else {
    print("I vincoli di Merton non sono soddisfatti")
  }
}

Check_Merton(S0, K, r, Time2Mat, callprice)
## [1] "I vincoli di Merton sono soddisfatti"

Questa funzione prende come input il prezzo iniziale dell’azione S0, il prezzo di esercizio K, il tasso privo di rischio r, il tempo alla scadenza Time2Mat e il prezzo dell’opzione Call cal lprice.

La funzione calcola il payoff attualizzato e verifica se i vincoli di Merton sono soddisfatti. Se i vincoli sono soddisfatti, la funzione stampa un messaggio affermativo, altrimenti stampa un messaggio negativo.

PROBLEMA 3

Utilizzando i pacchetti quantmod e fOptions scrivere un file in R che risolve i seguenti punti:

-Scaricare i prezzi di chiusura giornalieri di una serie finanziaria.

-Stimare la volatilitá storica dai log-rendimenti su base annua.

-Valutare un’opzione di tipo put europeo utilizzando la funzione CRRBinomialTreeOption con strike 1,05*S0 (S0 é il prezzo corrente del sottostante). Analizzare il comportamento del prezzo all’aumentare del numero di periodi.

# Caricamento dei pacchetti necessari
library(quantmod)
library(fOptions)

getSymbols("AMZN") #azioni AMAZON
## [1] "AMZN"
ClosePrice <- as.numeric(AMZN$AMZN.Close)

# stimare la volatilità dei log-rendimenti su base annua

#Sì stima la volatilità dei log-rendimenti su base giornaliera  
#calcolandoil momento secondo campionario del log-rendimenti

logRet <-diff(log(ClosePrice))
Sample2ndMom <- mean(logRet^2)

#si annualizza considerando 252 giorni

sigma <- sqrt(252*Sample2ndMom)

#Sì valuta una put europea con Strike pari a S0*1.05,
#analizzando i prezzi su diversi periodi

#S0 è l'ultimo prezzo di chiusura del sottostante

S0 <- tail(ClosePrice,1L)
Strike <- S0*1.05
TimeToMat <- 1/12 #Maturity mensile 
r <- 0.02 #tasso di interesse del 2%
N <- 5 #numero di step iniziale

#si utilizza la funzione di fOPtions CRRBinomialTreeOption
#per calcolare il prezzo della put europea
Put <- CRRBinomialTreeOption(TypeFlag = "pe",S=S0,X=Strike,
                             Time=TimeToMat,r=r,b=r, sigma=sigma, n=N)

cat("Il prezzo dell'opzione calcolata su 5 periodi è:",round(Put@price,4),"\n")
## Il prezzo dell'opzione calcolata su 5 periodi è: 6.9953
# Definizione del numero di periodi
num_periods <- c(10,50,150,500,1000,5000)

# Valutazione dell'opzione di tipo put europeo con la funzione CRRBinomialTreeOption

for (n in num_periods) {
price <- CRRBinomialTreeOption(TypeFlag = "pe", S = S0, X = Strike,Time = TimeToMat,r = r,b = r, sigma = sigma, n = n)@price
cat(paste0("Prezzo dell'opzione con ", n, " periodi: ", round(price,4), "\n"))}
## Prezzo dell'opzione con 10 periodi: 7.2652
## Prezzo dell'opzione con 50 periodi: 7.2147
## Prezzo dell'opzione con 150 periodi: 7.2004
## Prezzo dell'opzione con 500 periodi: 7.1951
## Prezzo dell'opzione con 1000 periodi: 7.1953
## Prezzo dell'opzione con 5000 periodi: 7.1964

Come si può notare dall’output il prezzo dell’opzione tende a convergere all’aumentare del numero di periodi attorno al valore reale dell’opzione europea sulle azioni Amazon, il cui prezzo con 5.000 periodi è di 7.1964.