R SHINY WEB APP FOR FINANCIAL PORTFOLIO ANALYSIS

My Reproductible Pitch presentation

Josue Afouda

2023-08-11

Introduction

Play with my Shiny web app at this link

App features

 Possibility for the user to choose any stock market index between the CAC40, the S&P500, the DAX, the FTSE100 and the Nikkei225;

 Possibility for the user to choose the number of assets constituting the portfolio as well as the weight of each asset;

 Retrieval of the daily closing prices of the Shares over a given period and possibility of saving them in CSV format;

 Display of statistics (average, median, quartiles, etc.) on closing prices;

 Closing price visualization charts (Histograms, line chart of each asset);

 Calculation of the Daily Yields of each Share and possibility of saving them in CSV format;

 Display of statistics (mean, median, quartiles, etc.) of Returns;

 Visualization of Yields (Histograms and Line Graphs);

 Calculation and visualization of correlations (correlation between each pair of assets);

 Visualization graphs of the evolution of the Beginning of Period and End of Period parameters;

 Aggregation of daily yields to obtain average annual, quarterly, monthly or weekly yields and possibility of saving them in CSV format;

 Calculation of moving annualized average returns, moving annualized volatilities, moving annualized sharpe ratios and visualization of their evolution (the user must be able to choose the size of the moving window. This size will be expressed in number of months);

 Calculation and Visualization of Drawdowns (potential losses);

 Portfolio optimization by different methods (Mean-Variance Efficient and Imposing Constraints);

 Optimization evaluation.

How i make this app?

# Libraries
library(PerformanceAnalytics)
library(quantmod)
library(tseries)
# Importation des données de plusieurs titres

stocks <- new.env()

stocks_names <- c("GOOG", "AMZN", "AAPL", "MSFT", "IBM")

getSymbols(stocks_names, 
           env = stocks, 
           from = as.Date('2015-01-01'), 
           to = as.Date('2020-01-01'))

# Extraction des prix de clôture de chaque titre pour en former un seul ensemble de données au format xts

close_prices <- do.call(merge, lapply(stocks, Cl))

# Affichage des premières observations

head(close_prices)

# Statistiques des prix de clôture

summary(close_prices)
# Histogrammes des prix de tous les stocks

par(mfrow = c(2, 3))

for (i in 1:ncol(close_prices)) {
  chart.Histogram(close_prices[, i], 
                  xlab = 'Prix de clôture')
}
# Prix de clôture au cours du temps

plot.zoo(close_prices, 
         main = 'Evolution des prix de clôture', 
         col = 1:ncol(close_prices))

# Calcul des rendements journaliers de chaque stock

stocks_daily_returns <- Return.calculate(close_prices)

# Suppression de la première ligne

stocks_daily_returns <- stocks_daily_returns[-1]
# Calcul des rendements du portefeuille à pondération égale

portfolio <- Return.portfolio(stocks_daily_returns, 
                             weights = c(1/5, 1/5, 1/5, 1/5, 1/5), 
                             rebalance_on = NA, 
                             verbose = TRUE)

# Fusion des rendements de stocks et du portefeuille

returns <- merge(stocks_daily_returns, portfolio$returns)

# Histogramme des rendements des stocks et de ceux du portefeuille

par(mfrow = c(2, 3))

for (i in 1:ncol(returns)) {
  
  chart.Histogram(returns[, i])
  
}
# Evolution des rendements des stocks et ceux du portefeuille

plot.zoo(returns, 
         main = 'Rendements des Stocks et du Portefeuille', 
         col = 1:ncol(returns) + 1)

# Evolution des BOP

plot.zoo(portfolio$BOP.Weight, 
         main = 'BOP.Weight', 
         col = 1:ncol(stocks_daily_returns))

# Evolution des EOP

plot.zoo(portfolio$EOP.Weight, 
         main = 'EOP.Weight', 
         col = 1:ncol(stocks_daily_returns))
# Rendements moyens mensuels du portefeuille

pf_monthly_returns <- apply.monthly(portfolio$returns, mean)

# Evolution au cours du temps des rendements moyens mensuels

plot(pf_monthly_returns, 
     main = "Rendements moyens mensuels du portefeuille")

addLegend("topleft", on=1, lty = 1, 
          legend.names = colnames(pf_monthly_returns))

# Corrélation entre les rendements des actifs

chart.Correlation(stocks_daily_returns, 
                  histogram = FALSE)
# Rendements moyens annualisés mobiles sur 12 mois

chart.RollingPerformance(R = pf_monthly_returns, 
                         width = 12,
                         FUN = "Return.annualized")

# Ecart-type des Rendements annualisés mobiles sur 12 mois

chart.RollingPerformance(R = pf_monthly_returns, 
                         width = 12,
                         FUN = "StdDev.annualized")

# Ratio de sharpe annualisés mobiles sur 12 mois

chart.RollingPerformance(R = pf_monthly_returns, 
                         width = 12,
                         FUN = "SharpeRatio.annualized")
# Pertes potentielles du portefeuille

chart.Drawdown(pf_monthly_returns, 
               main = "Evolution des pertes potentielles du portefeuille")

# Portefeuille efficace de moyenne-variance

opt1 <- portfolio.optim(
  apply.monthly(stocks_daily_returns, mean)
  )

# Poids optimaux du portefeuille de moyenne-variance

w <- opt1$pw

names(w) <- colnames(stocks_daily_returns)

print(w)

# Diagramme à barre montrant les poids optimaux

barplot(w)