This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
# Midterm Exam:
# Upload your url on RPubs to Tronclass.
#
# Download ETF daily data from yahoo with ticker names of SPY, QQQ, EEM, IWM, EFA,
# TLT, IYR and GLD from 2018 to 2022.
# 1. Load libraries
library(pacman)
p_load(tidyquant, lubridate, timetk, tidyverse, fPortfolio)
symbols <- c("SPY", "QQQ", "EEM", "IWM", "EFA", "TLT", "IYR", "GLD")
portfolioPrices <- NULL
# symbol = "SPY"
for (symbol in symbols){
portfolioPrices <- cbind(portfolioPrices,
getSymbols.yahoo(symbol, from = '2018-01-01', to = '2022-12-31', auto.assign = FALSE)[, 6])
}
portfolioPrices
## SPY.Adjusted QQQ.Adjusted EEM.Adjusted IWM.Adjusted EFA.Adjusted
## 2018-01-02 245.82840 152.88676 43.05478 143.94115 61.24227
## 2018-01-03 247.38338 154.37236 43.46730 144.09074 61.53624
## 2018-01-04 248.42607 154.64244 43.68253 144.47427 62.21066
## 2018-01-05 250.08153 156.19551 44.05919 144.77357 62.55651
## 2018-01-08 250.53882 156.80321 44.05919 144.99806 62.53921
## 2018-01-09 251.10594 156.81288 43.98744 144.80164 62.60839
## 2018-01-10 250.72179 156.44635 43.70943 144.82033 62.48735
## 2018-01-11 252.55106 157.51707 43.97848 147.30823 62.91966
## 2018-01-12 254.19746 158.67468 44.39996 147.92548 63.55085
## 2018-01-16 253.32846 158.22127 44.22957 146.03619 63.49034
## ...
## 2022-12-16 381.81281 273.17209 37.83000 173.72896 65.42000
## 2022-12-19 378.57516 269.33304 37.86000 171.37764 65.26000
## 2022-12-20 379.09320 269.12338 37.85000 172.28429 65.52000
## 2022-12-21 384.76157 273.02734 38.19000 175.25333 66.20000
## 2022-12-22 379.27249 266.34769 37.85000 172.96181 65.66000
## 2022-12-23 381.45419 266.94672 37.80000 173.74889 65.89000
## 2022-12-27 379.94992 263.17258 38.36000 172.58319 65.99000
## 2022-12-28 375.22794 259.69797 37.80000 169.90308 65.29000
## 2022-12-29 381.98218 266.02817 38.43000 174.20720 66.32000
## 2022-12-30 380.97598 265.86841 37.90000 173.71899 65.64000
## TLT.Adjusted IYR.Adjusted GLD.Adjusted
## 2018-01-02 112.31089 69.33669 125.15000
## 2018-01-03 112.84785 69.22485 124.82000
## 2018-01-04 112.82997 68.14094 125.46000
## 2018-01-05 112.50780 68.20976 125.33000
## 2018-01-08 112.43616 68.59688 125.31000
## 2018-01-09 110.93262 67.80544 124.73000
## 2018-01-10 110.79840 66.97960 125.03000
## 2018-01-11 111.25482 66.74731 125.44000
## 2018-01-12 111.44279 66.20535 126.96000
## 2018-01-16 111.90811 66.38599 127.17000
## ...
## 2022-12-16 106.30303 84.04142 166.78999
## 2022-12-19 104.51660 83.04708 166.32001
## 2022-12-20 102.66070 82.81839 169.08000
## 2022-12-21 102.91873 83.67352 168.80000
## 2022-12-22 102.89888 83.33544 166.75999
## 2022-12-23 101.39034 84.05137 167.25999
## 2022-12-27 99.38555 83.99171 168.67000
## 2022-12-28 98.80000 82.56981 167.91000
## 2022-12-29 99.92149 84.40933 168.85001
## 2022-12-30 98.80992 83.71329 169.64000
#
# 2. Calculate weekly and monthly returns using log returns
prices_weekly <- to.weekly(portfolioPrices, indexAt = "last", OHLC = FALSE)
prices_monthly <- to.monthly(portfolioPrices, indexAt = "last", OHLC = FALSE)
#
asset_returns_day_xts <- na.omit(Return.calculate(portfolioPrices))
asset_returns_wk_xts <- na.omit(Return.calculate(prices_weekly))
asset_returns_mon_xts <- na.omit(Return.calculate(prices_monthly))
head(asset_returns_day_xts)
## SPY.Adjusted QQQ.Adjusted EEM.Adjusted IWM.Adjusted EFA.Adjusted
## 2018-01-03 0.006325459 9.716967e-03 0.009581313 0.0010392940 0.0048001491
## 2018-01-04 0.004214891 1.749540e-03 0.004951428 0.0026617231 0.0109597110
## 2018-01-05 0.006663779 1.004297e-02 0.008622568 0.0020716570 0.0055594285
## 2018-01-08 0.001828566 3.890615e-03 0.000000000 0.0015506097 -0.0002766663
## 2018-01-09 0.002263615 6.169563e-05 -0.001628419 -0.0013546829 0.0011062396
## 2018-01-10 -0.001529853 -2.337381e-03 -0.006320070 0.0001290871 -0.0019332927
## TLT.Adjusted IYR.Adjusted GLD.Adjusted
## 2018-01-03 0.0047809859 -0.001612989 -0.0026368504
## 2018-01-04 -0.0001584051 -0.015657898 0.0051273786
## 2018-01-05 -0.0028553268 0.001010036 -0.0010361649
## 2018-01-08 -0.0006367560 0.005675368 -0.0001596128
## 2018-01-09 -0.0133723882 -0.011537482 -0.0046284751
## 2018-01-10 -0.0012099591 -0.012179609 0.0024051585
head(asset_returns_wk_xts)
## SPY.Adjusted QQQ.Adjusted EEM.Adjusted IWM.Adjusted EFA.Adjusted
## 2018-01-12 0.016458378 0.01587223 0.007734559 0.021771247 0.015894990
## 2018-01-19 0.008959256 0.01124686 0.018784049 0.002782212 0.008571459
## 2018-01-26 0.022003246 0.02759394 0.032513747 0.006305151 0.015108554
## 2018-02-02 -0.038837127 -0.03697398 -0.058179632 -0.036152760 -0.035880359
## 2018-02-09 -0.050644403 -0.05169831 -0.053618740 -0.045895027 -0.054583187
## 2018-02-16 0.044397663 0.05675851 0.067212492 0.044763771 0.041259701
## TLT.Adjusted IYR.Adjusted GLD.Adjusted
## 2018-01-12 -0.009466099 -0.029385966 0.013005643
## 2018-01-19 -0.011725518 0.006497022 -0.004253315
## 2018-01-26 0.004307014 0.016911862 0.013051805
## 2018-02-02 -0.030431241 -0.029325958 -0.013117887
## 2018-02-09 -0.013715058 -0.041590412 -0.012817492
## 2018-02-16 0.006529235 0.024290286 0.025567064
head(asset_returns_mon_xts)
## SPY.Adjusted QQQ.Adjusted EEM.Adjusted IWM.Adjusted EFA.Adjusted
## 2018-02-28 -0.036360318 -0.012927819 -0.058984954 -0.038436734 -0.048347815
## 2018-03-29 -0.027410686 -0.040788545 0.005414344 0.012175160 -0.008396243
## 2018-04-30 0.005168179 0.005058636 -0.028168837 0.009813749 0.015212714
## 2018-05-31 0.024309116 0.056729267 -0.026214952 0.061635806 -0.018942620
## 2018-06-29 0.005750861 0.011450250 -0.045456776 0.006143667 -0.015841149
## 2018-07-31 0.037046364 0.027964128 0.035310138 0.016490202 0.028520208
## TLT.Adjusted IYR.Adjusted GLD.Adjusted
## 2018-02-28 -0.030414501 -0.066573366 -0.020759902
## 2018-03-29 0.028596762 0.037719186 0.006320007
## 2018-04-30 -0.020881501 0.002252501 -0.009539745
## 2018-05-31 0.020043986 0.033712507 -0.011959209
## 2018-06-29 0.006458085 0.040594721 -0.036149448
## 2018-07-31 -0.014368738 0.008314499 -0.022418910
# Q1: Try to find the GMVP for these eight assets using the derived asset_returns data. ----
# Note that you have to compute optimal weights and GMVP returns using weekly and monthly asset returns.
# Q2: Given the portfolio return is specified as 0.045 annual rate. ----
# Try to find the optimal weights for the minimum variance portfolio.
# You should use weekly and monthly asset returns to derive the solutions.
# Q3. Find the tangency portfolio based on Q2. Risk-free rate is assumed to be zero.
# You should compute the tangency portfolio weights and its returns based on weekly
# monthly returns.
# Q4. The attached file "berndt.xslx" contains monthly returns of 15 stocks, market index returns (MARKET), ----
# and risk-free monthly rate (RKFREE) for 120 months.
# Compute GMVP (global minimum variance portfolio) weights and its return by using the covariance derived
# from single index model.
# Load necessary libraries
library(quadprog)
# Define expected returns and covariance matrix
expected_returns <- c(0.05, 0.06, 0.07, 0.08) # Example expected returns
cov_matrix <- matrix(c(0.02, 0.01, 0.005, 0.001,
0.01, 0.03, 0.004, 0.002,
0.005, 0.004, 0.04, 0.003,
0.001, 0.002, 0.003, 0.025), nrow = 4) # Example covariance matrix
# Define constraints and other parameters
Amat <- rbind(rep(1, length(expected_returns)), diag(length(expected_returns))) # Equality constraint: weights sum to 1
bvec <- c(1, rep(0, length(expected_returns))) # Right-hand side of the equality constraint
meq <- 1 # Number of equality constraints
Dmat <- 2 * cov_matrix # Quadratic term in the objective function (2 * covariance matrix)
dvec <- rep(0, length(expected_returns)) # Linear term in the objective function
# Solve the quadratic programming problem to get GMVP weights
result <- solve.QP(Dmat, dvec, t(Amat), bvec, meq = meq) # Note the transpose of Amat
# Extract the optimal weights
optimal_weights <- result$solution
# Calculate GMVP expected return and portfolio standard deviation (risk)
expected_return_gmvp <- optimal_weights %*% expected_returns
portfolio_std_gmvp <- sqrt(t(optimal_weights) %*% cov_matrix %*% optimal_weights)
# Print the results
cat("Optimal Weights (GMVP): ", optimal_weights, "\n")
## Optimal Weights (GMVP): 0.3431931 0.1624348 0.1555685 0.3388035
cat("Expected Return (GMVP): ", expected_return_gmvp, "\n")
## Expected Return (GMVP): 0.06489982
cat("Portfolio Standard Deviation (GMVP): ", portfolio_std_gmvp, "\n")
## Portfolio Standard Deviation (GMVP): 0.09800437
# Load necessary libraries
library(quadprog)
# Define expected returns and covariance matrix
expected_returns <- c(0.05, 0.06, 0.07, 0.08) # Example expected returns
cov_matrix <- matrix(c(0.02, 0.01, 0.005, 0.001,
0.01, 0.03, 0.004, 0.002,
0.005, 0.004, 0.04, 0.003,
0.001, 0.002, 0.003, 0.025), nrow = 4) # Example covariance matrix
# Define target portfolio return
target_return <- 0.045 # Example target return
# Define constraints and other parameters
Amat <- rbind(rep(1, length(expected_returns)), diag(length(expected_returns))) # Equality constraint: weights sum to 1
bvec <- c(1, rep(0, length(expected_returns))) # Right-hand side of the equality constraint
meq <- 1 # Number of equality constraints
Dmat <- 2 * cov_matrix # Quadratic term in the objective function (2 * covariance matrix)
dvec <- rep(0, length(expected_returns)) # Linear term in the objective function
# Define additional constraints for target portfolio return
Aeq <- expected_returns
beq <- target_return
# Combine equality constraints
Amat <- rbind(Amat, Aeq)
bvec <- c(bvec, beq)
# Solve the quadratic programming problem to get minimum variance portfolio weights
result <- solve.QP(Dmat, dvec, t(Amat), bvec, meq = meq) # Note the transpose of Amat
# Extract the optimal weights
optimal_weights <- result$solution
# Print the results
cat("Optimal Weights (Minimum Variance Portfolio): ", optimal_weights, "\n")
## Optimal Weights (Minimum Variance Portfolio): 0.3431931 0.1624348 0.1555685 0.3388035
# Load necessary libraries
library(quadprog)
library(readxl)
# Load data for Q1, Q2, and Q3
# Replace with your actual data
asset_returns_weekly <- data.frame(asset1 = c(0.01, 0.02, 0.03, 0.04, 0.02, 0.01, -0.01),
asset2 = c(0.02, 0.03, 0.01, -0.01, -0.02, 0.03, 0.02),
asset3 = c(0.03, 0.01, 0.02, -0.03, -0.01, -0.02, 0.01),
asset4 = c(0.01, -0.02, -0.01, 0.03, 0.02, 0.01, 0.02))
asset_returns_monthly <- data.frame(asset1 = c(0.05, -0.02, 0.03, -0.01, 0.02, 0.01),
asset2 = c(0.03, 0.04, -0.01, 0.02, 0.01, -0.03),
asset3 = c(-0.01, 0.02, 0.03, 0.01, -0.02, -0.01),
asset4 = c(0.02, -0.03, -0.02, 0.01, 0.03, 0.02))
portfolio_return_target <- 0.045
# Q1: GMVP for weekly returns
expected_returns_weekly <- colMeans(asset_returns_weekly)
cov_matrix_weekly <- cov(asset_returns_weekly)
Dmat_weekly <- 2 * cov_matrix_weekly
dvec_weekly <- rep(0, length(expected_returns_weekly))
Amat_weekly <- rbind(rep(1, length(expected_returns_weekly)), diag(length(expected_returns_weekly)))
bvec_weekly <- c(1, rep(0, length(expected_returns_weekly)))
meq_weekly <- 1
result_weekly <- solve.QP(Dmat_weekly, dvec_weekly, t(Amat_weekly), bvec_weekly, meq = meq_weekly)
optimal_weights_weekly <- result_weekly$solution
GMVP_return_weekly <- t(expected_returns_weekly) %*% optimal_weights_weekly
# Q2: Optimal weights for minimum variance portfolio with target return
Aeq_monthly <- colMeans(asset_returns_monthly)
beq_monthly <- portfolio_return_target
Amat_monthly <- rbind(Aeq_monthly, diag(length(expected_returns_weekly)))
bvec_monthly <- c(beq_monthly, rep(0, length(expected_returns_weekly)))
meq_monthly <- 1
result_monthly <- solve.QP(Dmat_weekly, dvec_weekly, t(Amat_monthly), bvec_monthly, meq = meq_monthly)
optimal_weights_monthly <- result_monthly$solution
# Q3: Tangency portfolio weights and returns
tangency_weights_monthly <- optimal_weights_monthly
tangency_return_monthly <- t(expected_returns_weekly) %*% tangency_weights_monthly
cat("\nQ3: Tangency portfolio weights and return (monthly):\n")
##
## Q3: Tangency portfolio weights and return (monthly):
print(tangency_weights_monthly)
## [1] 1.6403910 1.3436481 0.6496374 1.5052361
cat("Tangency portfolio return (monthly):", tangency_return_monthly, "\n")
## Tangency portfolio return (monthly): 0.05730704
cat("\nQ4: GMVP weights for single index model:\n")
##
## Q4: GMVP weights for single index model:
You can also embed plots, for example:
Note that the echo = FALSE parameter was added to the
code chunk to prevent printing of the R code that generated the
plot.