Vai al contenuto

Calcoli scientifici con Julia/Minimizzazione del rischio in finanza

Wikibooks, manuali e libri di testo liberi.
Indice del libro

In finanza quando si vuole ottenere il minor rischio possibile avendo n asset che costituiscono un portafoglio, costituito per esempio da n azioni, si risolve la questione, minimizzando la seguente funzione obiettivo:

dove è la varianza o volatività del portafoglio. Se un titolo ha un rendimento atteso del 7%, ma a volte fa +20% , a volte fa –15% allora è rischioso non perché perda sempre, ma perché è imprevedibile. La misura matematica di questa imprevedibilità è la varianza o volatilità del portafoglio che deve essere minimizzata.

invece è la matrice di covarianza e w il vettore dei pesi che rappresenta la percentuale del portafoglio investita in ciascun asset, ad esempio:

  • → 40% nell’asset 1
  • → 35% nell’asset 2
  • → 25% nell’asset 3

E valgono sempre:

e i pesi tutti positivi.

La matrice di covarianza è uno degli oggetti matematici più importanti nella finanza quantitativa.

Per un portafoglio con n asset, la matrice è:


Dove è la serie dei rendimenti dell’asset ( i ).

Sulla diagonale principale si trova la varianza dei vari asset per cui:

che misura la volatilità dell’asset (più è grande, più è rischioso)

Fuori diagonale la covarianza:

e misura se due asset si muovono insieme per cui se :

  • Cov > 0 → si muovono nella stessa direzione
  • Cov < 0 → si muovono in direzioni opposte
  • Cov ≈ 0 → movimenti indipendenti

Se si hanno due titoli dove:

  • uno sale quando l’altro scende → covarianza negativa → ottima diversificazione
  • si muovono sempre insieme → covarianza positiva → poca diversificazione
  • movimenti indipendenti → covarianza vicino a 0 → discreta diversificazione


Implementazione in Julia

[modifica | modifica sorgente]

Innanzitutto installo le librerie di Julia che mi servono:

using Pkg
Pkg.add(["Convex", "SCS", "LinearAlgebra","YFinance", "DataFrames", "Statistics"])

Supponiamo di considerare tre titoli : Apple (AAPL), Microsoft (MSFT), Google (GOOG) . Tramite il package YFinance scarico i prezzi giornalieri degli ultimi 5 anni e trasformo i dati in un DataFrame:

using YFinance, DataFrames, Statistics

tickers = ["AAPL", "MSFT", "GOOG"]

data =get_prices.(tickers, range="5y", interval="1d")
data = data |> DataFrame

Calcolo i rendimenti logaritmici dei prezzi di chiusura delle azioni dati dalla formula :

.

Ad esempio per Google i prezzi di chiusura si ottengono da :

 data[data.ticker.=="GOOG","close"]
1-element Vector{Vector{Float64}}:
[101.33550262451172, 102.45449829101562, 105.427001953125, 101.20850372314453, 102.63500213623047, 102.75150299072266, 105.7385025024414, 103.09600067138672, 103.32450103759766, 104.6259994506836  …  302.82000732421875, 303.94000244140625, 303.55999755859375, 314.8999938964844, 311.69000244140625, 310.9200134277344, 313.0299987792969, 307.1499938964844, 311.42999267578125, 306.3599853515625]

mentre i rendimenti si ottengono da:

function log_returns(prices)
    p = prices[1]
    return log.(p[2:end] ./ p[1:end-1])
end

# Calcolo i rendimenti per tutti i titoli
returns = DataFrame()

for t in tickers
    prices = data1[data1.ticker.==t,"close"]
    returns[!, t] = log_returns(prices)
end

first(returns, 5)

Calcolo la matrice di covarianza:

 Σ = cov(Matrix(returns))
3×3 Matrix{Float64}:
0.000301193  0.000172574  0.000192449
0.000172574  0.000273012  0.000195294
0.000192449  0.000195294  0.000372485

Per finire calcolo la varianza minima del portafoglio ed i relativi pesi:

using Convex, SCS

# numero di asset
n = 3

# variabile dei pesi
w = Variable(n)

# vincoli
constraints = [sum(w) == 1,
               w >= 0]

# funzione obiettivo: w' Σ w
objective = quadform(w, Σ)

# costruzione del problema
problem = minimize(objective, constraints)

# risoluzione
solve!(problem, SCS.Optimizer)

println("Pesi ottimali = ", evaluate(w))
println("Varianza minima = ", evaluate(objective))
 ------------------------------------------------------------------
	       SCS v3.2.11 - Splitting Conic Solver
	(c) Brendan O'Donoghue, Stanford University, 2012
 ------------------------------------------------------------------
 problem:  variables n: 5, constraints m: 11
 cones: 	  z: primal zero / dual free vars: 1
 l: linear vars: 3
 q: soc vars: 7, qsize: 2
 settings: eps_abs: 1.0e-04, eps_rel: 1.0e-04, eps_infeas: 1.0e-07
 alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
 max_iters: 100000, normalize: 1, rho_x: 1.00e-06
 acceleration_lookback: 10, acceleration_interval: 10
 compiled with openmp parallelization enabled
 lin-sys:  sparse-direct-amd-qdldl
 nnz(A): 19, nnz(P): 0
 ------------------------------------------------------------------
  iter | pri res | dua res |   gap   |   obj   |  scale  | time (s)
   ------------------------------------------------------------------
     0| 1.45e+01  1.00e+00  2.01e+01 -9.97e+00  1.00e-01  4.76e-03
   100| 5.78e-05  3.38e-05  3.09e-06  2.28e-04  1.00e-01  2.16e-02
  ------------------------------------------------------------------
  status:  solved
  timings: total: 2.16e-02s = setup: 1.08e-04s + solve: 2.15e-02s
	 lin-sys: 5.90e-05s, cones: 4.12e-05s, accel: 1.45e-05s
  ------------------------------------------------------------------
  objective = 0.000228
  ------------------------------------------------------------------
  [ Info: [Convex.jl] Compilation finished: 0.01 seconds, 199.312 KiB of memory allocated
  Pesi ottimali = [0.3484971984347163, 0.36753960780239314, 0.2839631923712822]
  Varianza minima = 0.000226558562734014

Conclusione:

Si ottiene una varianza minima di 0.000227 col 34,84% di Apple, il 36,75% di Microsoft e il 28,39% di Google nel portafoglio, ma dalla matrice di covarianza si vede che le covarianze sono tutte positive quindi c'è poca diversificazione, nel senso che se sale un titolo sale anche l'altro e viceversa, il che è normale perché tutti appartengono al settore tech USA.