投资组合回测的风险价值
Value at Risk for a Portfolio Backtest
我正在尝试为我的投资组合回测计算指标。我正在使用 R 包 PerformanceAnalytics
,并且我想 apply/use 它的函数 VaR
用于我实际重新平衡我的投资组合的每一年。这似乎行不通,尽管我很确定必须有一个简单的解决方案,因为我有我的 table 和所有需要的日志 returns,还有一个 table投资组合 weights/year。
我需要的是 optimize.portfolio.rebalancing
步骤后的 VaR/year。
port_ret <- portfolio.spec(assets=funds)
port_ret <- add.constraint(portfolio=port_ret, type="full_investment")
port_ret <- add.constraint(portfolio=port_ret, type="long_only")
port_ret <- add.constraint(portfolio=port_ret, type="box", min=0.0, max=0.2)
port_ret <- add.objective(portfolio=port_ret, type="quadratic_utility", risk_aversion=(4.044918))
port_ret <- add.objective(portfolio=port_ret, type="risk", name="StdDev")
port_ret <- add.objective(portfolio=port_ret, type="return", name="mean")
opt_rent<- optimize.portfolio(R=R, portfolio=port_ret, optimize_method="ROI", trace=TRUE)
plot(opt_rent, risk.col="StdDev", return.col="mean", main="Quadratic Utility Optimization", chart.assets=TRUE, xlim=c(0, 0.03), ylim=c(0, 0.002085))
extractStats(opt_rent)
bt_port_rent <- optimize.portfolio.rebalancing(R=R, portfolio= port_ret, optimize_method="ROI", rebalance_on="years", trace=TRUE, training_period= NULL)
chart.Weights(bt_port_rent, ylim=c(0, 1))
extractStats(bt_port_rent)
weights_rent <- round(extractWeights(bt_port_rent),3)
VaR(R, weights= weights_rent, portfolio_method="component",method="historical")
当前的 VaR 计算给我一个错误(R 是所用指数的每日 returns,weights_rent 是重新平衡的权重,见下文)。要补充的重要一点是 weights_rent 是年度数据,而区域 R 是每日数据:
requires numeric/complex matrix/vector arguments
我假设这是因为 VaR 计算需要权重向量而不是 table 20 行提供不同的权重,请参见下面的权重 table:
> weights_rent
SPX RUA FTSE DAX NKY MSCI EM GOLD ASIA50 SSE BBAG REX GSCI
1998-12-31 0.200 0.200 0.198 0.002 0 0.000 0.000 0.000 0.000 0.200 0.200 0.000
1999-12-31 0.200 0.159 0.000 0.188 0 0.000 0.000 0.200 0.076 0.177 0.000 0.000
2000-12-29 0.179 0.000 0.000 0.150 0 0.000 0.000 0.071 0.200 0.200 0.000 0.200
2001-12-31 0.147 0.000 0.000 0.045 0 0.000 0.077 0.122 0.200 0.200 0.200 0.010
2002-12-31 0.013 0.000 0.000 0.000 0 0.000 0.200 0.106 0.109 0.200 0.200 0.172
2003-12-31 0.000 0.053 0.000 0.000 0 0.000 0.200 0.137 0.071 0.200 0.200 0.140
2004-12-31 0.000 0.080 0.000 0.000 0 0.000 0.200 0.161 0.000 0.200 0.200 0.160
2005-12-30 0.000 0.070 0.000 0.000 0 0.000 0.200 0.193 0.000 0.200 0.145 0.191
2006-12-29 0.000 0.097 0.000 0.000 0 0.015 0.200 0.196 0.193 0.200 0.000 0.098
2007-12-31 0.000 0.008 0.000 0.017 0 0.130 0.200 0.125 0.200 0.200 0.000 0.120
2008-12-31 0.000 0.055 0.000 0.025 0 0.000 0.200 0.129 0.130 0.200 0.200 0.061
2009-12-31 0.000 0.051 0.000 0.010 0 0.007 0.200 0.145 0.162 0.200 0.200 0.024
2010-12-31 0.000 0.064 0.000 0.015 0 0.012 0.200 0.158 0.129 0.200 0.200 0.023
2011-12-30 0.000 0.098 0.000 0.000 0 0.000 0.200 0.149 0.119 0.200 0.200 0.035
2012-12-31 0.000 0.099 0.000 0.014 0 0.000 0.200 0.161 0.109 0.200 0.200 0.018
2013-12-31 0.000 0.134 0.000 0.025 0 0.000 0.200 0.146 0.095 0.200 0.200 0.000
2014-12-31 0.000 0.138 0.000 0.016 0 0.000 0.200 0.117 0.130 0.200 0.200 0.000
2015-12-31 0.000 0.129 0.000 0.041 0 0.000 0.200 0.102 0.127 0.200 0.200 0.000
2016-12-30 0.000 0.148 0.000 0.036 0 0.000 0.200 0.119 0.098 0.200 0.200 0.000
2017-12-29 0.000 0.151 0.000 0.018 0 0.000 0.200 0.146 0.085 0.200 0.200 0.000
2018-12-31 0.000 0.179 0.000 0.004 0 0.000 0.200 0.150 0.066 0.200 0.200 0.000
非常感谢您的帮助。提前致谢。
编辑测试数据:
#fake data
data(edhec)
ticker1 <- c("ConA","CTA","DisE","EM","EQN","EvD", "FIA", "GM", "LSE","MA", "RV", "SS","FF")
colnames(edhec) <- ticker1
fund.names <- colnames(edhec)
port_test <- portfolio.spec(assets=fund.names)
port_test <- add.constraint(portfolio=port_test, type="full_investment")
port_test <- add.constraint(portfolio=port_test, type="long_only")
port_test <- add.constraint(portfolio=port_test, type="box", min=0.0, max=0.2)
port_test <- add.objective(portfolio=port_test, type="quadratic_utility", risk_aversion=(4.044918))
port_test <- add.objective(portfolio=port_test, type="risk", name="StdDev")
port_test <- add.objective(portfolio=port_test, type="return", name="mean")
bt_port_test <- optimize.portfolio.rebalancing(R=edhec, portfolio= port_test, optimize_method="ROI", rebalance_on="years", trace=TRUE, training_period= NULL)
chart.Weights(bt_port_test, ylim=c(0, 1))
extractStats(bt_port_test)
weights_test <- round(extractWeights(bt_port_test),3)
weights_test
head(edhec)
#split data per year (result in list)
ret.year <- split(edhec, f="years")
#calculating yearly VaR
VaRs = rollapply(data = edhec, width = 20, FUN = function(x) VaR(x, p = 0.95, weights= weights_test, portfolio_method="component",method = "historical", by.column = TRUE))
我收到以下错误代码:
Error in VaR(x, p = 0.95, weights = weights_test, portfolio_method = "component", :
number of items in weights not equal to number of columns in R
如果尝试创建函数:
ret.year2 <- ret.year[-c(1,2)]
VAR <- function(p, ret.year2, weights.year){
a <- for(i in 1:ret.year2)
b <- for(j in 1:weights.year)
VaR(a,p=0.95,weights= b, portfolio_method="component",method = "historical")
}
resultat <- VAR(p=0.95,ret.year2=ret.year2, weights.year= weights.year)
不幸的是没有达到预期效果:
Error in 1:ret.year2 : NA/NaN argument
In addition: Warning message:
In 1:ret.year2 : numerical expression has 11 elements: only the first used
根据函数 documentation,错误的原因似乎是您自己提到的原因:weights
参数需要 vector
的权重 - 不是zoo
对象或其他东西。您可以尝试为 VaR
函数提供它想要的东西 - 一个数值向量。
而且,如果您想获得 20 个 VaR
函数值(R 中每年一个),一次提供 VaR
一年的 data/R 似乎是合乎逻辑的,最终会给你想要的 20 个函数值。
如果需要,您可以使流程自动化,并在循环中按年对数据进行子集化,一次 1 年,并将其提供给 VaR,然后打印结果或将其存储在某种数据结构中。
编辑:使用你的假数据,你可以这样分析它:
library(ROI)
library(ROI.plugin.quadprog)
library(ROI.plugin.glpk)
library(PerformanceAnalytics)
library(PortfolioAnalytics)
# your code here
#split data per year (result in list)
ret.year <- split(edhec, f="years")
# split weights per year
weights.year <- split(weights_test, f="years")
# loop over the list of weights, find corresponding data from edhec and run the analysis
for (i in 1:length(weights.year)){
weight <- weights.year[[i]]
year_weight <- as.numeric(format(start(weight), "%Y"))
weight <- as.vector(weight)
for (j in 1:length(ret.year)){
YearlyR <- ret.year[[j]]
year_R <- as.numeric(format(start(YearlyR), "%Y"))
if (year_R==year_weight){
print(paste("BINGO - years match: ", year_R, year_weight, sep=" "))
result <- VaR(YearlyR, weights= weight, portfolio_method="component",method="historical")
print(result)
}
}
}
我正在尝试为我的投资组合回测计算指标。我正在使用 R 包 PerformanceAnalytics
,并且我想 apply/use 它的函数 VaR
用于我实际重新平衡我的投资组合的每一年。这似乎行不通,尽管我很确定必须有一个简单的解决方案,因为我有我的 table 和所有需要的日志 returns,还有一个 table投资组合 weights/year。
我需要的是 optimize.portfolio.rebalancing
步骤后的 VaR/year。
port_ret <- portfolio.spec(assets=funds)
port_ret <- add.constraint(portfolio=port_ret, type="full_investment")
port_ret <- add.constraint(portfolio=port_ret, type="long_only")
port_ret <- add.constraint(portfolio=port_ret, type="box", min=0.0, max=0.2)
port_ret <- add.objective(portfolio=port_ret, type="quadratic_utility", risk_aversion=(4.044918))
port_ret <- add.objective(portfolio=port_ret, type="risk", name="StdDev")
port_ret <- add.objective(portfolio=port_ret, type="return", name="mean")
opt_rent<- optimize.portfolio(R=R, portfolio=port_ret, optimize_method="ROI", trace=TRUE)
plot(opt_rent, risk.col="StdDev", return.col="mean", main="Quadratic Utility Optimization", chart.assets=TRUE, xlim=c(0, 0.03), ylim=c(0, 0.002085))
extractStats(opt_rent)
bt_port_rent <- optimize.portfolio.rebalancing(R=R, portfolio= port_ret, optimize_method="ROI", rebalance_on="years", trace=TRUE, training_period= NULL)
chart.Weights(bt_port_rent, ylim=c(0, 1))
extractStats(bt_port_rent)
weights_rent <- round(extractWeights(bt_port_rent),3)
VaR(R, weights= weights_rent, portfolio_method="component",method="historical")
当前的 VaR 计算给我一个错误(R 是所用指数的每日 returns,weights_rent 是重新平衡的权重,见下文)。要补充的重要一点是 weights_rent 是年度数据,而区域 R 是每日数据:
requires numeric/complex matrix/vector arguments
我假设这是因为 VaR 计算需要权重向量而不是 table 20 行提供不同的权重,请参见下面的权重 table:
> weights_rent
SPX RUA FTSE DAX NKY MSCI EM GOLD ASIA50 SSE BBAG REX GSCI
1998-12-31 0.200 0.200 0.198 0.002 0 0.000 0.000 0.000 0.000 0.200 0.200 0.000
1999-12-31 0.200 0.159 0.000 0.188 0 0.000 0.000 0.200 0.076 0.177 0.000 0.000
2000-12-29 0.179 0.000 0.000 0.150 0 0.000 0.000 0.071 0.200 0.200 0.000 0.200
2001-12-31 0.147 0.000 0.000 0.045 0 0.000 0.077 0.122 0.200 0.200 0.200 0.010
2002-12-31 0.013 0.000 0.000 0.000 0 0.000 0.200 0.106 0.109 0.200 0.200 0.172
2003-12-31 0.000 0.053 0.000 0.000 0 0.000 0.200 0.137 0.071 0.200 0.200 0.140
2004-12-31 0.000 0.080 0.000 0.000 0 0.000 0.200 0.161 0.000 0.200 0.200 0.160
2005-12-30 0.000 0.070 0.000 0.000 0 0.000 0.200 0.193 0.000 0.200 0.145 0.191
2006-12-29 0.000 0.097 0.000 0.000 0 0.015 0.200 0.196 0.193 0.200 0.000 0.098
2007-12-31 0.000 0.008 0.000 0.017 0 0.130 0.200 0.125 0.200 0.200 0.000 0.120
2008-12-31 0.000 0.055 0.000 0.025 0 0.000 0.200 0.129 0.130 0.200 0.200 0.061
2009-12-31 0.000 0.051 0.000 0.010 0 0.007 0.200 0.145 0.162 0.200 0.200 0.024
2010-12-31 0.000 0.064 0.000 0.015 0 0.012 0.200 0.158 0.129 0.200 0.200 0.023
2011-12-30 0.000 0.098 0.000 0.000 0 0.000 0.200 0.149 0.119 0.200 0.200 0.035
2012-12-31 0.000 0.099 0.000 0.014 0 0.000 0.200 0.161 0.109 0.200 0.200 0.018
2013-12-31 0.000 0.134 0.000 0.025 0 0.000 0.200 0.146 0.095 0.200 0.200 0.000
2014-12-31 0.000 0.138 0.000 0.016 0 0.000 0.200 0.117 0.130 0.200 0.200 0.000
2015-12-31 0.000 0.129 0.000 0.041 0 0.000 0.200 0.102 0.127 0.200 0.200 0.000
2016-12-30 0.000 0.148 0.000 0.036 0 0.000 0.200 0.119 0.098 0.200 0.200 0.000
2017-12-29 0.000 0.151 0.000 0.018 0 0.000 0.200 0.146 0.085 0.200 0.200 0.000
2018-12-31 0.000 0.179 0.000 0.004 0 0.000 0.200 0.150 0.066 0.200 0.200 0.000
非常感谢您的帮助。提前致谢。
编辑测试数据:
#fake data
data(edhec)
ticker1 <- c("ConA","CTA","DisE","EM","EQN","EvD", "FIA", "GM", "LSE","MA", "RV", "SS","FF")
colnames(edhec) <- ticker1
fund.names <- colnames(edhec)
port_test <- portfolio.spec(assets=fund.names)
port_test <- add.constraint(portfolio=port_test, type="full_investment")
port_test <- add.constraint(portfolio=port_test, type="long_only")
port_test <- add.constraint(portfolio=port_test, type="box", min=0.0, max=0.2)
port_test <- add.objective(portfolio=port_test, type="quadratic_utility", risk_aversion=(4.044918))
port_test <- add.objective(portfolio=port_test, type="risk", name="StdDev")
port_test <- add.objective(portfolio=port_test, type="return", name="mean")
bt_port_test <- optimize.portfolio.rebalancing(R=edhec, portfolio= port_test, optimize_method="ROI", rebalance_on="years", trace=TRUE, training_period= NULL)
chart.Weights(bt_port_test, ylim=c(0, 1))
extractStats(bt_port_test)
weights_test <- round(extractWeights(bt_port_test),3)
weights_test
head(edhec)
#split data per year (result in list)
ret.year <- split(edhec, f="years")
#calculating yearly VaR
VaRs = rollapply(data = edhec, width = 20, FUN = function(x) VaR(x, p = 0.95, weights= weights_test, portfolio_method="component",method = "historical", by.column = TRUE))
我收到以下错误代码:
Error in VaR(x, p = 0.95, weights = weights_test, portfolio_method = "component", :
number of items in weights not equal to number of columns in R
如果尝试创建函数:
ret.year2 <- ret.year[-c(1,2)]
VAR <- function(p, ret.year2, weights.year){
a <- for(i in 1:ret.year2)
b <- for(j in 1:weights.year)
VaR(a,p=0.95,weights= b, portfolio_method="component",method = "historical")
}
resultat <- VAR(p=0.95,ret.year2=ret.year2, weights.year= weights.year)
不幸的是没有达到预期效果:
Error in 1:ret.year2 : NA/NaN argument
In addition: Warning message:
In 1:ret.year2 : numerical expression has 11 elements: only the first used
根据函数 documentation,错误的原因似乎是您自己提到的原因:weights
参数需要 vector
的权重 - 不是zoo
对象或其他东西。您可以尝试为 VaR
函数提供它想要的东西 - 一个数值向量。
而且,如果您想获得 20 个 VaR
函数值(R 中每年一个),一次提供 VaR
一年的 data/R 似乎是合乎逻辑的,最终会给你想要的 20 个函数值。
如果需要,您可以使流程自动化,并在循环中按年对数据进行子集化,一次 1 年,并将其提供给 VaR,然后打印结果或将其存储在某种数据结构中。
编辑:使用你的假数据,你可以这样分析它:
library(ROI)
library(ROI.plugin.quadprog)
library(ROI.plugin.glpk)
library(PerformanceAnalytics)
library(PortfolioAnalytics)
# your code here
#split data per year (result in list)
ret.year <- split(edhec, f="years")
# split weights per year
weights.year <- split(weights_test, f="years")
# loop over the list of weights, find corresponding data from edhec and run the analysis
for (i in 1:length(weights.year)){
weight <- weights.year[[i]]
year_weight <- as.numeric(format(start(weight), "%Y"))
weight <- as.vector(weight)
for (j in 1:length(ret.year)){
YearlyR <- ret.year[[j]]
year_R <- as.numeric(format(start(YearlyR), "%Y"))
if (year_R==year_weight){
print(paste("BINGO - years match: ", year_R, year_weight, sep=" "))
result <- VaR(YearlyR, weights= weight, portfolio_method="component",method="historical")
print(result)
}
}
}