# Preparazione dei dati
Il codice sotto (per visualizzare il codice cliccare sul tasto
code) mostrato crea una lista di ticker (i.e. simbolo
di un titolo) in tickerList e assegna a ciascuno di essi un
peso (weight). Successivamente, utilizza la funzione lapply
per scaricare i dati storici delle azioni corrispondenti a ciascun
ticker dal sito Yahoo Finance, utilizzando la funzione
getSymbols. I dati vengono scaricati per il periodo
compreso tra il 15 dicembre 2017 e il 16 dicembre 2022. Una volta
scaricati i dati, essi vengono memorizzati in un oggetto
stockData. In questo modo, potrete avere accesso ai dati
storici di diversi titoli.
tickerList = c("SPG", # REITS
"OHI",
"CCOM.TO", # Commodities
"DBC",
"FCX",
"KSM-F6.TA",
"0P0001MN8G.F", # CAT BOND
"CDZ.TO", # dividend
"NOBL",
"NSRGY",
"CNI",
"WFAFY",
"UU.L",
"KO",
"NVS",
"NVDA", # nvidia no dividendi
# "SHY", # short term bond -- in verità sono etf che riproducono l'andamento
# "VGSH",
"SPTS",
"IBGS.AS",
"6C=F", # cash -- ho messo un future sui dollari canadesi per rappresentare la liquidità
# "XT2D.L", # swap -- non sapevo cosa mettere
"XGIU.MI") # Inflation linked
# weightOLD = c(.12,.13,.07,.11,.15,.23,.19)
weight = c(
.08,
.06,
.046, # comodities
.009,
.01,
.057,
.07, # cat bond
.02, # div
.06,
.02,
.01,
.017,
.005,
.005,
.05,
.023,
# .07,
# .07,
.05,
.128,
.15,
# .00,
.13
)
sum(weight)
## [1] 1
stockData = lapply(1:length(tickerList),
function(i)
getSymbols(
Symbols = tickerList[i],
src = "yahoo",
from = as.Date("2018-09-30"),
to = as.Date("2023-09-29"),
auto.assign = F
))
tickerList[tickerList == "KSM-F6.TA"] = "KSM.F6.TA"
tickerList[tickerList == "6C=F"] = "X6C"
Il codice sotto mostrato unisce i dati delle diverse azioni scaricate
in precedenza in un unico oggetto nominalPortfolio
utilizzando la funzione merge. In seguito, elimina le osservazioni
mancanti dall’oggetto utilizzando la funzione na.omit. Infine, il codice
esegue un ciclo per ciascun ticker presente nella lista
tickerList, seleziona le colonne del
nominalPortfolio che corrispondono al ticker in questione e
che non sono relative al volume, e divide queste colonne per il valore
del primo giorno di osservazione per quel ticker, ottenendo così gli
indici a base fissa equivalente al primo giorno della serie storica. In
questo modo, i dati del nominalPortfolio vengono
normalizzati in base al valore del primo giorno di osservazione per
ciascun ticker.
nominalPortfolio = do.call(merge,stockData) %>%
na.omit
nominalPortfolio$X0P0001MN8G.F.Volume = 1
for(i in 1:length(tickerList))
{
# print(i)
columnSelect = (!names(nominalPortfolio) %like% "Volume") & names(nominalPortfolio) %like% tickerList[i]
nominalPortfolio[,columnSelect] = nominalPortfolio[,columnSelect] / rep(coredata(nominalPortfolio[1,columnSelect])[1],5)
}
as_tibble(nominalPortfolio)
Il grafico mostra il risultato di una serie di operazioni effettuate
sui dati del portafoglio in una matrice chiamata portfolio.
In particolare, questo codice utilizza un ciclo for per
iterare attraverso ogni ticker nella lista tickerList. Per
ciascun ticker, il codice utilizza una selezione di colonne basata sulla
condizione che i nomi delle colonne non contengano Volume e
contengano il ticker corrente. Una volta selezionate le colonne
corrette, il codice moltiplica i valori delle colonne selezionate con i
pesi corrispondenti del titolo, che sono contenuti nel vettore
weight[i].
portfolio = nominalPortfolio
for(i in 1:length(tickerList))
{
columnSelect = (!names(portfolio) %like% "Volume") & names(portfolio) %like% tickerList[i]
portfolio[,columnSelect] = coredata(nominalPortfolio[,columnSelect]) * weight[i]
}
as_tibble(portfolio)
Il codice sotto mostrato crea una matrice myPortfolio
vuota e assegna i nomi delle colonne utilizzando la lista
columnNames. Successivamente, esegue un ciclo per ciascuna
colonna e seleziona le colonne del portfolio che
corrispondono al nome della colonna in questione. In seguito, utilizza
la funzione sapply per calcolare la somma di tutte le colonne
selezionate per ogni riga della matrice myPortfolio. Una
volta completata la matrice, viene assegnato a myPortfolio
il formato xts (time series) utilizzando l’indice del
portfolio come data di riferimento. In questo modo, avrete
a disposizione i dati del vostro portafoglio in formato xts e potrete
utilizzarli per analizzare le performance del portafoglio o per fare
previsioni sui futuri andamenti dei mercati.
columnNames = c("Open", "High", "Low", "Close", "Volume", "Adjusted")
myPortfolio = matrix(NA, nrow(portfolio),ncol = length(columnNames))
for(i in 1:length(columnNames))
{
columnSelect = names(portfolio) %like% columnNames[i]
myPortfolio[,i] = sapply(1:nrow(portfolio), function(r) sum(coredata(portfolio[r,columnSelect])))
}
colnames(myPortfolio) = paste("Ragionevole", columnNames, sep = ".")
myPortfolio = xts(myPortfolio, order.by = index(portfolio))
as_tibble(myPortfolio)
Il seguente pezzo di codice è utilizzato per analizzare l’andamento mensile del portafoglio e “decomporre” la serie storica in tre componenti distinte: un andamento stagionale, un andamento tendenziale e una componente casuale.
La funzione decompose() utilizzata nel codice è una
funzione di base di R che utilizza un algoritmo di decomposizione
chiamato “stima e filtraggio”. Questo algoritmo analizza la serie
storica e separa i dati in queste tre componenti.
La prima riga di codice utilizza la funzione
to.monthly() per convertire i dati del portafoglio da
giornalieri a mensili, in modo da avere una visione più generale
dell’andamento del portafoglio. La seconda riga utilizza
decompose() per effettuare la decomposizione e salva il
risultato nella variabile pfDecomposto.
In sintesi, questo pezzo di codice ci permette di analizzare l’andamento mensile del portafoglio e ci fornisce una comprensione più profonda dei fattori che influenzano l’andamento del portafoglio, sia a livello stagionale che tendenziale. Ci aiuta ad identificare possibili opportunità e rischi, per fare previsioni più informate.
# weeklyPortfolio = Cl(to.weekly(myPortfolio))
# pfDecomposto = decompose(as.ts(weeklyPortfolio, start=c(2022,9,29)))
# plot(pfDecomposto)
In questo capitolo, ci concentreremo sull’ottimizzazione del portafoglio. Il nostro obiettivo è trovare il giusto equilibrio tra il rischio misurato dal VaR e il rendimento del portafoglio. Per raggiungere questo obiettivo, ci concentreremo sull’assegnazione del peso appropriato per ogni singolo titolo del portafoglio.
È importante notare che basare la valutazione di un titolo solo sul rendimento medio degli ultimi anni e sulla sua varianza può essere restrittivo. Questo metodo non tiene conto di molti altri fattori che influiscono sull’andamento di un titolo. Pertanto, abbiamo stabilito dei vincoli sull’ottimizzazione per garantire che i pesi scelti vengano migliorati senza essere stravolti.
Il codice calcola i rendimenti per ogni titolo, trasforma i rendimenti in contributi annuali e elimina eventuali valori mancanti. Quindi, calcola la media dei rendimenti per ogni titolo, la matrice di covarianza per i rendimenti trimestrali dei titoli, il Value at Risk per i rendimenti trimestrali del portafoglio e il rischio del portafoglio utilizzando la matrice di covarianza e pesi del portafoglio. Infine, calcola il rapporto di Sharpe, una metrica comunemente utilizzata per valutare la performance del portafoglio rispetto al rischio.
nominalPortfolioAdj = nominalPortfolio[,names(nominalPortfolio) %like% "Adjusted"] %>%
CalculateReturns() %>%
to.yearly.contributions() %>%
na.omit()
nominalPortfolioAdj = nominalPortfolioAdj[,names(nominalPortfolioAdj) != "Portfolio Return"]
mean_ret <- colMeans(nominalPortfolioAdj)
cov_mat = nominalPortfolio[,names(nominalPortfolio) %like% "Adjusted"] %>%
CalculateReturns() %>%
to.quarterly.contributions() %>%
na.omit() %>%
cov()
# solo quando i volumi non sono degeneri
# return3mesi = nominalPortfolio %>%
# CalculateReturns() %>%
# to.period.contributions("quarters") %>%
# na.omit()
#
# var3m = VaR(R = return3mesi[,names(return3mesi) %like% "Adjusted"],
# method = "historical",
# portfolio_method = "component",
# weights = weight)
# port_risk = var3m$hVaR
cov_mat = cov_mat[rownames(cov_mat) != "Portfolio Return",
colnames(cov_mat) != "Portfolio Return"]
port_returns = sum(mean_ret * weight)
port_risk <- sqrt(t(weight) %*% (cov_mat %*% weight))
sharpe_ratio <- port_returns/port_risk
tibble("Return" = port_returns,
"Risk" = port_risk,
# "VaR a 3 mesi" = var3m$hVaR,
"Sharpe ratio" = sharpe_ratio)
Il seguente pezzo di codice è dedicato alla ricerca dei valori. Vengono generati 5000 portafogli diversi, con diversi pesi dei titoli che compongono il portafoglio. Ogni portafoglio viene poi valutato con le metriche precedentemente descritte.
Infine, nei successivi pezzi di codice vengono mostrati dei grafici che rappresentano il lavoro dell’algoritmo appena descritto. L’ultimo grafico è il più importante, nella quale si può vedere la distribuzione della frontiera efficiente, ovvero l’insieme dei valori con miglior sharpe ratio. Per scegliere i pesi più adatti alle proprie necessità ci sono due tecniche. La prima consiste nel fissare il VaR e cercare il rendimento più alto. La seconda, invece, è l’opposto. Fissato il rendimento desiderato, si minimizza il VaR.
set.seed(1)
num_port <- 5000
# Creating a matrix to store the weights
all_wts <- matrix(nrow = num_port,
ncol = length(tickerList))
# Creating an empty vector to store
# Portfolio returns
port_returns <- vector('numeric', length = num_port)
# Creating an empty vector to store
# Portfolio Standard deviation
port_risk <- vector('numeric', length = num_port)
# Creating an empty vector to store
# Portfolio Sharpe Ratio
sharpe_ratio <- vector('numeric', length = num_port)
for (i in seq_along(port_returns)) {
precisione = 0.9
wts = sapply(1:length(weight), function(i) runif(1,precisione * weight[i], (2 - precisione) * weight[i]))
# wts = runif(length(tickerList))
wts <- wts/sum(wts)
# Storing weight in the matrix
all_wts[i,] <- wts
# Portfolio returns
port_ret <- sum(wts * mean_ret)
# port_ret <- ((port_ret + 1)^252) - 1
# Storing Portfolio Returns values
port_returns[i] <- port_ret
# Creating and storing portfolio risk
port_sd <- sqrt(t(wts) %*% (cov_mat %*% wts))
# Più preciso ma ci mette troppo
# port_sd = VaR(
# R = return3mesi[, names(return3mesi) %like% "Adjusted"],
# method = "historical",
# portfolio_method = "component",
# weights = wts
# )$hVaR
port_risk[i] <- port_sd
# Creating and storing Portfolio Sharpe Ratios
# Assuming 0% Risk free rate
sr <- port_ret/port_sd
sharpe_ratio[i] <- sr
}
Di seguito vengono mostrati i pesi assegnati dal portafoglio con sharpe ratio maggiore.
# Storing the values in the table
portfolio_values <- tibble(Return = port_returns,
Risk = port_risk,
SharpeRatio = sharpe_ratio)
# Converting matrix to a tibble and changing column names
all_wts <- all_wts %>%
data.frame() %>%
tibble
colnames(all_wts) <- tickerList
# Combing all the values together
portfolio_values <- tibble(cbind(all_wts, portfolio_values))
colnames(portfolio_values)[1:length(tickerList)] = tickerList
min_var <- portfolio_values[which.min(portfolio_values$Risk),]
max_sr <- portfolio_values[which.max(portfolio_values$SharpeRatio),]
weightOLD = weight
weight = max_sr[,1:length(tickerList)] %>%
as.numeric() %>%
round(4)
# con l'arrotondamento potrebbe non fare 1 e lo calibro con il primo titolo, ciò non influenzerà significativamente sullo scostamento del portafoglio
weight[1] = weight[1] + 1 - sum(weight)
max_sr
I grafici di seguito riportati sono interattivi, posizionandosi sopra con il mouse si potranno osservare maggiori informazioni.
p <- min_var %>%
gather(1:length(tickerList), key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Titoli', y = 'Pesi', title = "Pesi del portafoglio con VaR minimo") +
scale_y_continuous(labels = scales::percent) +
theme(legend.position = "none") +
coord_flip()
ggplotly(p)
p <- max_sr %>%
gather(tickerList[1]:tickerList[length(tickerList)], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Titoli',
y = 'Pesi',
title = "Pesi del portafoglio tangente alla frontiera efficiente") +
scale_y_continuous(labels = scales::percent) +
theme(legend.position = "none") +
coord_flip()
ggplotly(p)
p <- portfolio_values %>%
ggplot(aes(x = Risk, y = Return, color = SharpeRatio)) +
geom_point() +
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Rischio annuo',
y = 'Rendimento annuo',
title = "Ottimizzazione di portafoglio e frontiera efficiente") +
geom_point(aes(x = Risk,
y = Return),
data = min_var,
color = 'violet') +
geom_point(aes(x = Risk,
y = Return),
data = max_sr,
color = 'aquamarine')
ggplotly(p)
# Da esguire se si vuole rendimento più alto ma con diversificazione minore
# weightOLD = weight
# weight = portfolio_values[round(portfolio_values$SharpeRatio, 6) == 2.670734 & round(portfolio_values$Risk, 5) == 0.030190,1:length(tickerList)] %>%
# as.numeric() %>%
# round(4)
#
# # con l'arrotondamento potrebbe non fare 1 e lo calibro con il primo titolo, ciò non influenzerà significativamente sullo scostamento del portafoglio
# weight[1] = weight[1] + 1 - sum(weight)
# ricreo il portafoglio con i nuovi pesi
portfolio = nominalPortfolio
for(i in 1:length(tickerList))
{
columnSelect = (!names(portfolio) %like% "Volume") & names(portfolio) %like% tickerList[i]
portfolio[,columnSelect] = coredata(nominalPortfolio[,columnSelect]) * weight[i]
}
columnNames = c("Open", "High", "Low", "Close", "Volume", "Adjusted")
myPortfolio = matrix(NA, nrow(portfolio),ncol = length(columnNames))
for(i in 1:length(columnNames))
{
columnSelect = names(portfolio) %like% columnNames[i]
myPortfolio[,i] = sapply(1:nrow(portfolio), function(r) sum(coredata(portfolio[r,columnSelect])))
}
colnames(myPortfolio) = paste("Ragionevole", columnNames, sep = ".")
myPortfolio = xts(myPortfolio, order.by = index(portfolio))
returnTicker = xts()
for(i in 1:length(tickerList))
returnTicker = cbind(returnTicker,dailyReturn(Cl(nominalPortfolio[,names(portfolio) %like% tickerList[i]])))
colnames(returnTicker) = tickerList
returnTickerIndici = returnTicker %>%
as.tibble() %>%
summarise_all(sum) %>%
pivot_longer(1:length(tickerList), names_to = "Titoli", values_to = "Rendimento") %>%
add_column(returnTicker %>%
as.tibble() %>%
summarise_all(sd) %>%
pivot_longer(1:length(tickerList), names_to = "Titoli", values_to = "Varianza") %>%
dplyr::select(Varianza)
) %>%
mutate(Variazione = ifelse(round(Rendimento, 2) != 0,
Varianza/abs(Rendimento),
1))
## Warning: `as.tibble()` was deprecated in tibble 2.0.0.
## ℹ Please use `as_tibble()` instead.
## ℹ The signature and semantics have changed, see `?as_tibble`.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
returnTickerIndici %>%
ggplot(aes(Titoli, Variazione, fill = Varianza)) +
geom_col() +
coord_flip() +
scale_fill_gradient2(high = "mediumvioletred",
# mid = "mediumvioletred",
low = "mediumspringgreen",
midpoint = median(returnTickerIndici$Varianza))
returnTickerIndici %>%
ggplot(aes(y = Rendimento, x = Titoli, fill = Varianza)) +
geom_col() +
coord_flip() +
scale_fill_distiller(palette = "RdYlGn", direction = -1)
# ylim(c(-0.08,0.12))
returnTicker %>%
as.tibble() %>%
pivot_longer(1:length(tickerList), names_to = "Titoli", values_to = "Rendimento") %>%
ggplot(aes(y = Rendimento, x = Titoli)) +
geom_boxplot() +
coord_flip() +
ylim(c(-0.08,0.12))
## Warning: Removed 6 rows containing non-finite values (`stat_boxplot()`).
Il VaR è una misura del rischio che indica la perdita massima probabile che il portafoglio potrebbe subire con un determinato livello di confidenza. Nel caso specifico, il codice calcola il VaR utilizzando il metodo storico e un livello di confidenza del 95%.
Il codice inizia dividendo il portafoglio in trimestri e calcolando i rendimenti per ogni trimestre utilizzando la funzione CalculateReturns(). Quindi, utilizzando la funzione to.period.contributions() si trasformano i rendimenti in contributi trimestrali e si estraggono solo quelli che contengono “Adjusted” nel loro nome. Successivamente, con la funzione VaR() si calcola il VaR utilizzando i rendimenti trimestrali estratti, i pesi del portafoglio, il metodo storico e il metodo per il portafoglio “component”, il quale indica che il VaR è calcolato per ogni componente del portafoglio e poi sommato.
Infine, è importante notare che il VaR calcolato utilizzando il metodo storico si basa sui dati storici del portafoglio e potrebbe non essere un indicatore preciso del rischio futuro. Pertanto, sarebbe opportuno utilizzare anche altre metodologie per valutare il rischio del portafoglio, come ad esempio il Value at Risk condizionale o l’analisi di stress.
return3mesi = nominalPortfolio %>%
CalculateReturns %>%
to.period.contributions("quarters")
weight_max_sr = max_sr %>%
t() %>%
head(length(tickerList)) %>%
as.vector()
VaR(return3mesi[,names(return3mesi) %like% "Adjusted"],
method = "historical",
weights = weight_max_sr,
portfolio_method = "marginal") %>%
pivot_longer(1:length(weight_max_sr)+1, names_to = "Titoli", values_to = "VaR") %>%
mutate(VaR = round(VaR *100, 2)) %>%
ggplot(aes(x = Titoli, y = VaR, fill = VaR)) +
geom_col() +
coord_flip() +
scale_fill_distiller(palette = "RdYlGn", direction = -1) +
theme(legend.position = "none")
VaR(return3mesi[,names(return3mesi) %like% "Adjusted"] %>% na.omit(),
method = "historical",
weights = weight_max_sr,
portfolio_method = "component")
## $hVaR
## hVaR 95%
## -0.01108171
##
## $contribution
## SPG.Adjusted OHI.Adjusted CCOM.TO.Adjusted
## NaN NaN NaN
## DBC.Adjusted FCX.Adjusted KSM.F6.TA.Adjusted
## NaN NaN NaN
## X0P0001MN8G.F.Adjusted CDZ.TO.Adjusted NOBL.Adjusted
## NaN NaN NaN
## NSRGY.Adjusted CNI.Adjusted WFAFY.Adjusted
## NaN NaN NaN
## UU.L.Adjusted KO.Adjusted NVS.Adjusted
## NaN NaN NaN
## NVDA.Adjusted SPTS.Adjusted IBGS.AS.Adjusted
## NaN NaN NaN
## X6C.F.Adjusted XGIU.MI.Adjusted
## NaN NaN
##
## $pct_contrib_hVaR
## SPG.Adjusted OHI.Adjusted CCOM.TO.Adjusted
## NaN NaN NaN
## DBC.Adjusted FCX.Adjusted KSM.F6.TA.Adjusted
## NaN NaN NaN
## X0P0001MN8G.F.Adjusted CDZ.TO.Adjusted NOBL.Adjusted
## NaN NaN NaN
## NSRGY.Adjusted CNI.Adjusted WFAFY.Adjusted
## NaN NaN NaN
## UU.L.Adjusted KO.Adjusted NVS.Adjusted
## NaN NaN NaN
## NVDA.Adjusted SPTS.Adjusted IBGS.AS.Adjusted
## NaN NaN NaN
## X6C.F.Adjusted XGIU.MI.Adjusted
## NaN NaN
Nel seguente grafico è rappresentato l’istogramma dei rendimenti trimestrali simulati da una distribuzione normale con media pari al rendimento medio del portafoglio e deviazione standard pari alla volatilità del portafoglio. In questo caso il VaR è calcolato con il metodo gaussiano.
media = sapply(1:nrow(return3mesi), function(i) sum(return3mesi[i,names(nominalPortfolio) %like% "Adjusted"] * weight)) %>% mean(na.rm = T)
varianza = sapply(1:nrow(return3mesi), function(i) sum(return3mesi[i,names(nominalPortfolio) %like% "Adjusted"] * weight)) %>% sd(na.rm = T)
set.seed(1)
df = data.frame(x = rnorm(1E6, media, varianza))
ggplot(df, aes(x, ..density..)) +
geom_histogram(color = "violet",
fill = "orchid1",
alpha = .5) +
geom_density(color = "aquamarine") +
geom_vline(xintercept = quantile(df$x, probs = .05),
color = "aquamarine2") +
annotate('text',
x = quantile(df$x, probs = .05),
y = 0.01,
color = "aquamarine4",
label = paste("VaR = ",df$x %>%
quantile(probs = .05) %>%
round(4))) +
theme_light()
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Un correlogramma è un tipo di grafico che mostra la relazione di correlazione tra diverse variabili. Nel codice specifico, il correlogramma mostra la relazione di correlazione tra i diversi titoli che compongono il portafoglio.
Il codice inizia calcolando la matrice di correlazione tra i rendimenti trimestrali dei titoli estratti tramite il comando cor() e si omettono i valori mancanti. Successivamente, i nomi delle colonne e delle righe vengono modificati in modo da rimuovere il suffisso “.Adjusted”. Infine, utilizzando la libreria corrplot e il metodo “number” si crea il correlogramma, con titolo “Correlogramma dei titoli che compongono il portafoglio”, utilizzando il metodo “ward.D2” per l’elaborazione dei cluster e impostando “diag” a F in modo che non venga mostrato la diagonale del correlogramma, che rappresenta la correlazione di un titolo con se stesso.
Come consulente finanziario, è importante notare che la correlazione tra i titoli che compongono il portafoglio può influire significativamente sulla performance del portafoglio e sulla sua diversificazione. Il correlogramma ci permette di visualizzare rapidamente quali titoli sono correlati tra loro e di prendere decisioni informate su quali titoli includere o escludere dal portafoglio.
correlazione = return3mesi[,names(return3mesi) %like% "Adjusted"] %>%
na.omit %>%
cor
colnames(correlazione) = stringr::str_remove(colnames(correlazione),".Adjusted")
rownames(correlazione) = stringr::str_remove(colnames(correlazione),".Adjusted")
# correlazione %>%
# corrplot::corrplot(method = "number",
# # title = "Correlogramma dei titoli che compongono il portafoglio",
# hclust.method = "ward.D2",
# diag = F,
# type = "upper")
correlazione %>%
reshape2::melt() %>%
ggplot(aes(x=Var1, y=Var2, fill=value)) +
geom_tile() +
scale_fill_distiller(palette = "RdYlGn")
Il grafico che segue mostra i diversi titoli che compongono il vostro portafoglio, indicizzati in base al valore del primo giorno di osservazione della serie storica.
Il grafico è interattivo: posizionando il mouse sopra, sarà possibile visualizzare i valori degli indici per ciascun titolo, facilitando il confronto tra i diversi titoli e il loro andamento nel tempo. Questo vi permetterà di avere una panoramica dettagliata delle prestazioni del vostro portafoglio e di valutare se le vostre scelte di investimento sono state proficue.
grafico = highchart(type = "stock")
for(i in 1:length(tickerList))
grafico = hc_add_series(grafico,
Cl(nominalPortfolio[,names(portfolio) %like% tickerList[i]]),
name = tickerList[i])
grafico
Il grafico seguente, simile al precedente, mostra invece gli indici dei titoli e i relativi pesi con cui il vostro portafoglio è caratterizzato. Attraverso questo grafico, potrete comprendere meglio come le variazioni di un titolo influiscano sul vostro portafoglio. Potrete facilmente individuare quali titoli hanno un maggiore impatto sulle performance del portafoglio e valutare se i pesi assegnati alle diverse posizioni sono adeguati al vostro profilo di rischio e agli obiettivi di investimento. In questo modo, potrete prendere decisioni informate su come allocare il vostro portafoglio e ottimizzare le prestazioni.
grafico = highchart(type = "stock")
for(i in 1:length(tickerList))
grafico = hc_add_series(grafico,
Cl(portfolio[,names(portfolio) %like% tickerList[i]]),
name = tickerList[i])
grafico
Il codice sotto mostrato restituisce il rendimento giornaliero del vostro portafoglio, calcolato utilizzando i dati del prezzo di chiusura delle posizioni che compongono il portafoglio. Successivamente, viene generato un grafico di performance che riassume le prestazioni del portafoglio nel tempo. In questo modo, potrete avere una panoramica chiara e dettagliata delle performance del vostro portafoglio e valutare se le vostre scelte di investimento sono state proficue. Questo vi permetterà di prendere decisioni informate e di adattare il vostro portafoglio alle condizioni di mercato in evoluzione.
returnMyPortfolio = dailyReturn(Cl(myPortfolio))
charts.PerformanceSummary(as.xts(returnMyPortfolio))
Il codice sopra mostrato calcola il rendimento giornaliero per ciascun titolo che compone il vostro portafoglio, utilizzando i dati del prezzo di chiusura delle posizioni. I rendimenti vengono poi inseriti in un oggetto xts e i nomi delle colonne vengono impostati sulla lista dei ticker (i titoli che compongono il vostro portafoglio). Infine, viene generato un grafico di performance che riassume le prestazioni dei singoli titoli nel vostro portafoglio. In questo modo, potrete avere una panoramica dettagliata delle performance dei singoli titoli che compongono il vostro portafoglio e valutare l’impatto di ciascun titolo sulle prestazioni complessive del portafoglio. Questo vi permetterà di prendere decisioni informate su come allocare il vostro portafoglio e ottimizzare le prestazioni.
# returnTicker = xts()
# for(i in 1:length(tickerList))
# returnTicker = cbind(returnTicker,dailyReturn(Cl(nominalPortfolio[,names(portfolio) %like% tickerList[i]])))
# colnames(returnTicker) = tickerList
charts.PerformanceSummary(returnTicker,main = "Performance portafoglio Ragionevole")
chartSeries(myPortfolio)
Il codice sotto mostrato utilizza la libreria forecast per prevedere il comportamento futuro del vostro portafoglio utilizzando un modello ARIMA. Primo, viene specificato il numero di periodi che si desidera prevedere (variabile \(n\)). Successivamente, i dati del vostro portafoglio vengono suddivisi in una parte di training e una di test, utilizzando le prime \(n\) osservazioni come set di test. Il modello ARIMA viene quindi addestrato utilizzando i dati di training e viene effettuata la previsione per il set di test. Infine, viene generato un grafico che mostra le previsioni del modello e i dati di test, consentendo di valutare l’accuratezza delle previsioni del modello. In questo modo, potrete utilizzare il modello ARIMA per fare previsioni sulle performance future del vostro portafoglio e prendere decisioni informate su come allocare il vostro portafoglio in futuro.
# Number of period we want to forecast
n <- 100
# Splitting the data
train <- head(Cl(myPortfolio), length(Cl(myPortfolio))-n)
test <- tail(Cl(myPortfolio), n)
library(forecast)
# Forecast the data
fc_na <- forecast(auto.arima(train), h=n)
# Plot the result
autoplot(fc_na) +
autolayer(ts(test, start=length(train)), series = "Test Data")
Il modello ARIMA (Auto-Regressive Integrated Moving Average) è una combinazione di modelli autoregressivi, di integrazione di differenziazione e di media mobile. Il modello autoregressivo (AR) definisce il rapporto tra un’osservazione e alcune osservazioni con ritardo. Per utilizzare il modello ARIMA, i dati delle serie temporali devono diventare stazionari e ciò può essere ottenuto effettuando la differenza dei dati. Infine, il modello di media mobile (MA) definisce il rapporto tra un’osservazione e l’errore residuo del modello di media mobile sulle osservazioni con ritardo.
I modelli ARIMA vengono generalmente indicati con ARIMA (\(p, d, q\)), dove \(p\), \(d\) e \(q\) sono i parametri con valori positivi. L’ordine di AR (\(p\)) è il numero di osservazioni con ritardo nel modello. Per la differenziazione, abbiamo d come numero di volte in cui i dati effettivi vengono differenziati per diventare stazionari. Di solito, il massimo numero di differenziazioni per ottenere la stazionarietà è 2 volte. L’ordine di MA (\(q\)) è la dimensione della finestra di media mobile.
Esistono modi per determinare i valori appropriati di questi
parametri per il nostro modello, ma sono difficili. Fortunatamente, in R
abbiamo la funzione auto.arima() che svolgerà questo lavoro
per noi. Quando si utilizza questa funzione, esistono due tipi di ARIMA
che possiamo ottenere: ARIMA non stagionale (quello che abbiamo discusso
prima) e ARIMA stagionale. Ovviamente, nell’ARIMA non stagionale non
includiamo la parte stagionale dei dati, mentre nell’ARIMA stagionale la
includiamo. Vedremo quale dei due produca il miglior risultato di
previsione per i nostri dati.