是否有 R 函数如何通过找到投资组合资产的最佳权重来最小化跟踪误差
Is there an R function how to minimize the Tracking Error by finding optimal weights of portfolio assets
假设我有一个投资组合,共有 n 个资产及其在 x 个时期内的 return 以及同期基准的 return。我的 objective 是找到一个权重向量 w 使得
w∗=arg 最小 TE(w)
其中 TE(w) 是跟踪误差,定义如下:
TE = (sum((return.portfolio-return.benchmark)^2)/(x - 1))^0.5
简而言之,我想在 x 个时期内使用包含 n 个资产的投资组合来复制基准的 return。唯一的限制应该是所有资产的总和等于 1,并且没有资产的权重高于 0.4。
有人知道我如何用 R 解决这个问题吗?
有几个选项。这是来自 stats
的 constrOptim
:
#some data
library(quantmod)
library(PerformanceAnalytics)
getReturns <- function(symbols, from='2000-01-01') {
returns <- list()
for (symbol in symbols) { #symbol=symbols[2]
sym = getSymbols(symbol, from = from, adjustOHLC = TRUE, auto.assign = FALSE)
return <- Return.calculate(Ad(sym))
colnames(return) <- gsub("\.Adjusted", "", colnames(return))
returns[[symbol]] <- return
}
returns <- do.call(cbind, returns)
return(returns)
}
symbols <- c("MSFT","AAPL","AMZN","CSCO","ADBE")
ret <- getReturns(symbols,from="2020-01-01")[-1,]
x = nrow(ret) # periods
N = ncol(ret) # assets
set.seed(1324)
Bench = rnorm(x,0.0015,0.03) #some benchmark
plot(ts(Bench))
# const opt
## needs a feasible starting value
# A'b >= b0 x < 0.4 --> -x >= -.4 x> -0.4 or 0 if not short selling
#
fTE <- function(b,rets,Ben) {
Pret=apply(rets,1,function(rl)sum(rl*b))
sd(Pret-Ben)
}
upblim=0.4
loblim=-0.4
Amat <- matrix(1, 1, N)
Amat <- rbind(Amat,-diag(N)) # upper limit
Amat <- rbind(Amat,diag(N)) # if lower limit
bvec <- c(.9999999,rep(-upblim,N),rep(loblim,N))
# feasable sol
ws=c(3,4,5,6,1)
(ws=ws/sum(ws))
Amat %*% ws >= bvec
(sol <- constrOptim(ws, fTE, NULL, ui = Amat, ci = bvec,rets=ret,Ben=Bench))
sum(sol$par)
pie(abs(sol$par),labels = colnames(ret))
#> data.frame(Assets=colnames(ret),ws=sol$par)
# Assets ws
#1 MSFT -0.13233070
#2 AAPL 0.39999989
#3 AMZN 0.39999997
#4 CSCO 0.26382163
#5 ADBE 0.06850912
假设我有一个投资组合,共有 n 个资产及其在 x 个时期内的 return 以及同期基准的 return。我的 objective 是找到一个权重向量 w 使得
w∗=arg 最小 TE(w)
其中 TE(w) 是跟踪误差,定义如下:
TE = (sum((return.portfolio-return.benchmark)^2)/(x - 1))^0.5
简而言之,我想在 x 个时期内使用包含 n 个资产的投资组合来复制基准的 return。唯一的限制应该是所有资产的总和等于 1,并且没有资产的权重高于 0.4。
有人知道我如何用 R 解决这个问题吗?
有几个选项。这是来自 stats
的 constrOptim
:
#some data
library(quantmod)
library(PerformanceAnalytics)
getReturns <- function(symbols, from='2000-01-01') {
returns <- list()
for (symbol in symbols) { #symbol=symbols[2]
sym = getSymbols(symbol, from = from, adjustOHLC = TRUE, auto.assign = FALSE)
return <- Return.calculate(Ad(sym))
colnames(return) <- gsub("\.Adjusted", "", colnames(return))
returns[[symbol]] <- return
}
returns <- do.call(cbind, returns)
return(returns)
}
symbols <- c("MSFT","AAPL","AMZN","CSCO","ADBE")
ret <- getReturns(symbols,from="2020-01-01")[-1,]
x = nrow(ret) # periods
N = ncol(ret) # assets
set.seed(1324)
Bench = rnorm(x,0.0015,0.03) #some benchmark
plot(ts(Bench))
# const opt
## needs a feasible starting value
# A'b >= b0 x < 0.4 --> -x >= -.4 x> -0.4 or 0 if not short selling
#
fTE <- function(b,rets,Ben) {
Pret=apply(rets,1,function(rl)sum(rl*b))
sd(Pret-Ben)
}
upblim=0.4
loblim=-0.4
Amat <- matrix(1, 1, N)
Amat <- rbind(Amat,-diag(N)) # upper limit
Amat <- rbind(Amat,diag(N)) # if lower limit
bvec <- c(.9999999,rep(-upblim,N),rep(loblim,N))
# feasable sol
ws=c(3,4,5,6,1)
(ws=ws/sum(ws))
Amat %*% ws >= bvec
(sol <- constrOptim(ws, fTE, NULL, ui = Amat, ci = bvec,rets=ret,Ben=Bench))
sum(sol$par)
pie(abs(sol$par),labels = colnames(ret))
#> data.frame(Assets=colnames(ret),ws=sol$par)
# Assets ws
#1 MSFT -0.13233070
#2 AAPL 0.39999989
#3 AMZN 0.39999997
#4 CSCO 0.26382163
#5 ADBE 0.06850912