In this tutorial, I explain how to implement, in a flexible way, the algorithm of Bai, Lumsdaine, and Stock (1998).
Step 1: Lag variables.
This function takes as argument a matrix of time series observations and lags it by an order (q).
Code
compute_lags <- function(Y #time series matrix Y
, q) #lag order q
{
p <- dim(Y)[1] #get the dimensions
n <- dim(Y)[2]
myDates <- rownames(Y)[(q + 1) : p] #optional: keep the rownames dates of the data frame with final matching
Y <- data.
In this tutorial, I quickly describe how to compute and update an efficient frontier in adding stocks to an existing porfolio with R.
Step 1: Efficient frontier
First let’s write a simple code for an efficient frontier computation
Code
efficient_frontier = function(MRet #matrix of returns (MRet)
, rangeMu) #range (sequence) of target expected returns (rangeMu)
{
uM <- dim(MRet)[1] #get the row (uM) and column (pM) dimensions of the matrix of returns
pM <- dim(MRet)[2]
expRet <- colMeans(MRet) #compute the portfolio's individual stocks expected returns
Omega = var(MRet) #compute the sample var-covar matrix
unityVec <- rep(1, pM) #define a constraints vector (weights of the portfolio must sum to one)
A <- rbind(expRet, unityVec) #define a matrix of constraints (weights sum to one and variance will match a #target level of expected returns) n <- length(rangeMu) #get the length of the target range (sequence)
myVar <- rep(NA, n) #define an empty variance vector
myWeights <- matrix(data = NA, nrow = n, ncol = pM) #define an empty matrix of weights for each stock at each level of target
#expected returns
for(i in 1:n) #loop over the target expected returns range and compute variances and weights { b <- matrix(data = c(rangeMu[i], 1), nrow = 2)
myVar[i] <- t(b) %*% solve(A %*% solve(Omega) %*% t(A)) %*% b
myWeights[i,] <- solve(Omega) %*% t(A) %*% solve(A %*% solve(Omega) %*% t(A)) %*% b
}
mySd <- myVar^0.