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.