library(quadprog)
library(xts)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(PerformanceAnalytics)
##
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
##
## legend
Load and Prepare Data
data(EuStockMarkets)
stocks <- as.data.frame(EuStockMarkets)
Calculate Daily Log Returns
log_prices <- log(as.matrix(stocks)) # convert to matrix first
returns <- diff(log_prices) # log returns (one row shorter than prices)
Estimate Mean Returns and Covariance Matrix
# The EuStockMarkets dataset starts on 1991-01-02 and is daily (250 trading days/year)
start_date <- as.Date("1991-01-02")
dates <- seq(from = start_date, by = "days", length.out = nrow(returns))
returns_xts <- xts(returns, order.by = dates) # add date index
Markowitz Portfolio Optimization
mean_returns <- colMeans(returns_xts)
cov_matrix <- cov(returns_xts)
Portfolio Performance (Annualized)
Dmat <- 2 * cov_matrix
dvec <- rep(0, ncol(returns_xts))
Amat <- cbind(rep(1, ncol(returns_xts)), diag(1, ncol(returns_xts)))
bvec <- c(1, rep(0, ncol(returns_xts)))
result <- solve.QP(Dmat, dvec, Amat, bvec, meq = 1)
opt_weights <- round(result$solution, 4)
names(opt_weights) <- colnames(returns_xts)
print(opt_weights)
## DAX SMI CAC FTSE
## 0.0000 0.3229 0.0000 0.6771
Cumulative Return Visualization
portfolio_return <- sum(opt_weights * mean_returns) * 252
portfolio_risk <- sqrt(t(opt_weights) %*% cov_matrix %*% opt_weights) * sqrt(252)
cat("Expected Annual Return: ", round(portfolio_return * 100, 2), "%\n")
## Expected Annual Return: 14.03 %
cat("Expected Annual Risk (Std Dev): ", round(portfolio_risk * 100, 2), "%\n")
## Expected Annual Risk (Std Dev): 11.96 %
# Step 7: Visualize Cumulative Returns
portfolio_returns <- Return.portfolio(R = returns_xts, weights = opt_weights)
chart.CumReturns(portfolio_returns, main = "Cumulative Return of Optimized Portfolio", legend.loc = "topleft")
#Conclusion
In this analysis, we successfully implemented the Markowitz Mean-Variance Portfolio Optimization model using historical data from four major European indices. By solving for the minimum variance portfolio under a no-short-selling constraint:
The optimal weights were computed.
The expected annual return and risk were estimated.
A cumulative performance chart was plotted.
This demonstrates how classical portfolio theory can be applied using historical market data to construct a well-diversified, low-risk investment portfolio—even using data already available within R.