Data Acquisition
getSymbols(c("AAPL", "TSLA", "MSFT", "WMT"))
## [1] "AAPL" "TSLA" "MSFT" "WMT"
p.aapl <- AAPL[,6]
p.tsla <- TSLA[,6]
p.msft <- MSFT[,6]
p.wmt <- WMT[,6]
p.all <- merge(p.aapl, p.tsla)
p.all <- merge(p.all, p.msft)
p.all <- merge(p.all, p.wmt)
p.all <- na.omit(p.all)
r.aapl <- dailyReturn(AAPL[,6])
r.tsla <- dailyReturn(TSLA[,6])
r.msft <- dailyReturn(MSFT[,6])
r.wmt <- dailyReturn(WMT[,6])
r.all <- merge(r.aapl, r.tsla)
r.all <- merge(r.all, r.msft)
r.all <- merge(r.all, r.wmt)
r.all <- na.omit(r.all)
colnames(r.all) <- c("AAPL", "TSLA", "MSFT", "WMT")
r.all[1,]
## AAPL TSLA MSFT WMT
## 2010-06-29 -0.04521044 0 -0.04113537 -0.01351607
r.all[dim(r.all)[1],]
## AAPL TSLA MSFT WMT
## 2024-07-02 0.01623993 0.1019727 0.00558314 0.008743277
r_precovid <- window(r.all, start = "2010-06-29", end = "2019-12-31")
r_covid <- window(r.all, start = "2020-01-01", end = "2021-12-31")
r_postcovid <- window(r.all, start = "2022-01-01", end = "2024-07-02")
# Returns Descriptive Statistics
describe(r_precovid)
## vars n mean sd median trimmed mad min max range skew kurtosis se
## AAPL 1 2394 0 0.02 0 0 0.01 -0.12 0.09 0.21 -0.22 4.62 0
## TSLA 2 2394 0 0.03 0 0 0.02 -0.19 0.24 0.44 0.51 6.29 0
## MSFT 3 2394 0 0.01 0 0 0.01 -0.11 0.10 0.22 0.08 6.57 0
## WMT 4 2394 0 0.01 0 0 0.01 -0.10 0.11 0.21 0.16 16.11 0
describe(r_covid)
## vars n mean sd median trimmed mad min max range skew kurtosis se
## AAPL 1 505 0.00 0.02 0 0.00 0.02 -0.13 0.12 0.25 -0.01 5.26 0
## TSLA 2 505 0.01 0.05 0 0.01 0.03 -0.21 0.20 0.41 0.09 3.43 0
## MSFT 3 505 0.00 0.02 0 0.00 0.01 -0.15 0.14 0.29 -0.08 9.46 0
## WMT 4 505 0.00 0.02 0 0.00 0.01 -0.09 0.12 0.21 1.05 12.67 0
describe(r_postcovid)
## vars n mean sd median trimmed mad min max range skew kurtosis se
## AAPL 1 627 0 0.02 0 0 0.01 -0.06 0.09 0.15 0.28 2.31 0
## TSLA 2 627 0 0.04 0 0 0.03 -0.12 0.15 0.28 0.08 1.26 0
## MSFT 3 627 0 0.02 0 0 0.02 -0.08 0.08 0.16 0.08 1.65 0
## WMT 4 627 0 0.01 0 0 0.01 -0.11 0.07 0.18 -1.42 15.24 0
cor(r_precovid)
## AAPL TSLA MSFT WMT
## AAPL 1.0000000 0.2453949 0.4473265 0.2204632
## TSLA 0.2453949 1.0000000 0.2550375 0.1297112
## MSFT 0.4473265 0.2550375 1.0000000 0.3014131
## WMT 0.2204632 0.1297112 0.3014131 1.0000000
cor(r_covid)
## AAPL TSLA MSFT WMT
## AAPL 1.0000000 0.4666709 0.8062024 0.4731757
## TSLA 0.4666709 1.0000000 0.4766670 0.1544624
## MSFT 0.8062024 0.4766670 1.0000000 0.5159741
## WMT 0.4731757 0.1544624 0.5159741 1.0000000
cor(r_postcovid)
## AAPL TSLA MSFT WMT
## AAPL 1.0000000 0.5415414 0.6956278 0.2561616
## TSLA 0.5415414 1.0000000 0.4232098 0.1497285
## MSFT 0.6956278 0.4232098 1.0000000 0.2362502
## WMT 0.2561616 0.1497285 0.2362502 1.0000000
# Price and Return Time Series
par(mfrow = c(2,4))
plot(p.all[,1], main = "AAPL Price")
plot(p.all[,2], main = "TSLA Price")
plot(p.all[,3], main = "MSFT Price")
plot(p.all[,4], main = "WMT Price")
plot(r.all[,1], main = "AAPL")
plot(r.all[,2], main = "TSLA")
plot(r.all[,3], main = "MSFT")
plot(r.all[,4], main = "WMT")

par(mfrow = c(1,1))
# Return Histograms
par(mfrow = c(3,4))
hist(r_precovid[,1], main = "AAPL Pre-COVID", xlim = c(-0.25, 0.15))
hist(r_precovid[,2], main = "TSLA Pre-COVID", xlim = c(-0.25, 0.15))
hist(r_precovid[,3], main = "MSFT Pre-COVID", xlim = c(-0.25, 0.15))
hist(r_precovid[,4], main = "WMT Pre-COVID", xlim = c(-0.25, 0.15))
hist(r_covid[,1], main = "AAPL COVID", xlim = c(-0.25, 0.15))
hist(r_covid[,2], main = "TSLA COVID", xlim = c(-0.25, 0.15))
hist(r_covid[,3], main = "MSFT COVID", xlim = c(-0.25, 0.15))
hist(r_covid[,4], main = "WMT COVID", xlim = c(-0.25, 0.15))
hist(r_postcovid[,1], main = "AAPL Post-COVID", xlim = c(-0.25, 0.15))
hist(r_postcovid[,2], main = "TSLA Post-COVID", xlim = c(-0.25, 0.15))
hist(r_postcovid[,3], main = "MSFT Post-COVID", xlim = c(-0.25, 0.15))
hist(r_postcovid[,4], main = "WMT Post-COVID", xlim = c(-0.25, 0.15))

par(mfrow = c(1,1))
Rolling Correlation Matrix Plots
# Assuming df is your data frame with N time series
# N is the number of time series, T is the length of each time series
# Parameters
H <- 150 # Number of days for rolling correlation
T <- dim(r.all)[1]
num_series <- ncol(r.all) # Number of time series
# Calculate rolling correlations
correlations <- matrix(NA, nrow = T, ncol = choose(num_series, 2))
col_counter <- 1
for (i in 1:(num_series - 1)) {
for (j in (i + 1):num_series) {
ts1 <- r.all[, i]
ts2 <- r.all[, j]
rolling_cor <- rollapplyr(cbind(ts1, ts2), width = H, FUN = function(x) cor(x[,1], x[,2]), by.column = FALSE, align = "right")
correlations[, col_counter] <- rolling_cor
col_counter <- col_counter + 1
}
}
# Plotting
plot_titles <- combn(colnames(r.all), 2, paste, collapse = " vs ")
par(mfrow = c(3, 2)) # Adjust rows and columns as needed for your number of time series
for (k in 1:ncol(correlations)) {
plot(correlations[, k], type = 'l', xlab = 'Time', ylab = 'Correlation', main = paste("Rolling correlation:", plot_titles[k]), ylim = c(-0.1, 1))
}

# Reset plotting parameters
par(mfrow = c(1, 1)) # Reset to default plotting layout
Portfolio Allocation
#install.packages("DEOptim")
#library(DEOptim)
#install.packages("PortfolioAnalytics")
library(PortfolioAnalytics)
## Loading required package: foreach
## Loading required package: PerformanceAnalytics
##
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
##
## legend
?portfolio.spec
## starting httpd help server ...
## done
Port1 <- portfolio.spec(assets=colnames(r.all))
?add.constraint
Port1 <- add.constraint(Port1, type="full_investment")
Port1 <- add.constraint(Port1, type="long_only")
?add.objective
Port1 <- add.objective(Port1, type="risk", name="StdDev")
?optimize.portfolio
result <- optimize.portfolio(r.all, portfolio = Port1)
## Leverage constraint min_sum and max_sum are restrictive,
## consider relaxing. e.g. 'full_investment' constraint should be min_sum=0.99 and max_sum=1.01
## Iteration: 1 bestvalit: 0.011039 bestmemit: 0.046000 0.014000 0.260000 0.680000
## Iteration: 2 bestvalit: 0.011039 bestmemit: 0.046000 0.014000 0.260000 0.680000
## Iteration: 3 bestvalit: 0.011039 bestmemit: 0.046000 0.014000 0.260000 0.680000
## Iteration: 4 bestvalit: 0.011039 bestmemit: 0.046000 0.014000 0.260000 0.680000
## Iteration: 5 bestvalit: 0.011039 bestmemit: 0.046000 0.014000 0.260000 0.680000
## Iteration: 6 bestvalit: 0.011039 bestmemit: 0.046000 0.014000 0.260000 0.680000
## Iteration: 7 bestvalit: 0.011039 bestmemit: 0.046000 0.014000 0.260000 0.680000
## Iteration: 8 bestvalit: 0.011039 bestmemit: 0.046000 0.014000 0.260000 0.680000
## [1] 0.046 0.014 0.260 0.680