Cren
Forumer storico
Come ho promesso a ender85, pubblico un piccolo codice dimostrativo.
L'obiettivo è quello di costruire un indice sintetico partendo dai dati storici di quattro ETF; l'indice pesa i quattro costituenti con l'obiettivo di minimizzare la varianza del portafoglio.
L'indice rappresenta anche una forma di back test per Piedi a Terra che si chiedeva quanto valesse una strategia "passiva" di replica a varianza minima.
Per un privato nella realtà è ovviamente impossibile bilanciare con quella frequenza a causa dei costi di transazione e dei tempi di reazione, ma il codice è solo dimostrativo per mostrare la semplicità con cui si gestisce una ottimizzazione multipla e in finestra mobile su quattro sottostanti contemporaneamente.
Se non erro, nessun programma commerciale, al momento, è in grado di gestire un back test di questa complessità con questa velocità e semplicità di linguaggio, ma sarei felice di essere smentito.
A ender85 buon divertimento!
Interfacciare quindi R ad AmiBroker può consentire di unire due potenti strumenti per i back test.
L'obiettivo è quello di costruire un indice sintetico partendo dai dati storici di quattro ETF; l'indice pesa i quattro costituenti con l'obiettivo di minimizzare la varianza del portafoglio.
Codice:
[COLOR="SeaGreen"]#******************************************************************
# Minimum variance portfolio by Cren
#******************************************************************
# Carichiamo alcuni pacchetti di cui avremo bisogno[/COLOR]
require(quantmod)
require(fPortfolio)
require(timeSeries)
[COLOR="SeaGreen"]# Scarichiamo da Yahoo i dati storici dei quattro ETF che useremo.
# Le asset class scelte sono S&P500, Long Term US Treasury, oro e
# materie prime[/COLOR]
getSymbols(c('SPY', 'TLT', 'GLD', 'DBC'), from = '1950-01-01')
[COLOR="SeaGreen"]# Costruiamo un'unica matrice di dati con tutti e quattro gli ETF. Inoltre
# creiamo una matrice vuota di pesi che riempiremo successivamente
[/COLOR]
X <- na.omit(cbind(SPY[,4], TLT[,4], GLD[,4], DBC[,4]))
weights <- matrix(0, nrow = nrow(X), ncol = ncol(X))
[COLOR="SeaGreen"]# All'interno di una finestra mobile di 200 giorni calcoliamo il valore
# dei pesi che, giorno per giorno, minimizzano la volatilità.
# L'ampiezza della finestra può essere modificata a piacimento
# col parametro "k".[/COLOR]
k <- 199
for(i in 1:(nrow(X)-k)) {
data = X[i:(i+k),]
spec <- portfolioSpec()
setType(spec) <- 'LPM'
portf <- minvariancePortfolio(data = na.omit(returns(as.timeSeries(data), method = 'discrete')), spec = spec)
weights[i+k,] <- getWeights(portf)
}
[COLOR="SeaGreen"]# Visualizziamo le serie storiche degli ETF[/COLOR]
plot(as.timeSeries(X), plot.type = 'm', main = '')
[COLOR="SeaGreen"]# Visualizzamo l'evoluzione nel tempo dei pesi ottimali
[/COLOR]
plot(ylab = 'Minimum variance weight', timeSeries(weights, charvec = rownames(as.timeSeries(X))), plot.type = 's') ; grid() ; legend('topright', legend = c('SPY', 'TLT', 'GLD', 'DBC'), col = seq(1, 4, 1), lwd = rep(2, 4), bty = 'n')
[COLOR="SeaGreen"]# Calcoliamo i rendimenti del nostro nuovo portafoglio a minima varianza
[/COLOR]
dX <- returns(X, method = 'continuous') ; dX[1,] <- 0
w.ret <- weights * dX
ret <- rowSums(w.ret)
[COLOR="SeaGreen"]# Confrontiamo graficamente il portafoglio a minima varianza con i rendimenti
# delle altre asset class considerate singolarmente: sembra coerente![/COLOR]
plot(ylim = c(-.65, 1.25), lwd = 2, ylab = 'Return', as.timeSeries(cumsum(ret))) ; grid()
for(i in 1:4) {
lines(as.timeSeries(cumsum(dX[,i])), col = i + 1)
}
legend('topleft', legend = c('MinVar', 'SPY', 'TLT', 'GLD', 'DBC'), col = seq(1, 5, 1), lwd = rep(2, 5), bty = 'n')
Per un privato nella realtà è ovviamente impossibile bilanciare con quella frequenza a causa dei costi di transazione e dei tempi di reazione, ma il codice è solo dimostrativo per mostrare la semplicità con cui si gestisce una ottimizzazione multipla e in finestra mobile su quattro sottostanti contemporaneamente.
Se non erro, nessun programma commerciale, al momento, è in grado di gestire un back test di questa complessità con questa velocità e semplicità di linguaggio, ma sarei felice di essere smentito.
A ender85 buon divertimento!
Interfacciare quindi R ad AmiBroker può consentire di unire due potenti strumenti per i back test.
Allegati
Ultima modifica: