问题描述
我有一个 xts 文件,其中包含 17 个行业投资组合的月回报。数据如下:
Cars Chems Clths Cnstr Cnsum Durbl FabPr Finan Food Machn mines Oil Other Rtail Steel Trans
1926-07-31 4.77 1.20 -0.09 4.20 2.05 1.33 0.61 0.44 0.46 2.06 2.65 -2.57 1.99 1.46 3.05 -0.69
1926-08-31 -1.11 3.55 3.57 0.85 4.10 0.75 -0.49 8.84 4.72 5.57 1.16 3.85 4.81 0.63 -0.58 4.96
1926-09-30 -3.39 1.85 -4.89 -1.06 2.50 1.27 -3.10 -2.55 1.66 0.52 1.44 -4.93 -2.09 -1.20 2.28 0.06
1926-10-31 -10.66 -9.15 0.49 -6.49 -1.41 -5.02 -3.92 -4.40 -4.79 -4.52 5.73 0.23 -3.50 -2.44 -4.98 -2.79
1926-11-30 -0.73 4.98 2.66 2.91 8.35 0.12 1.36 -0.27 7.04 -0.75 1.13 2.92 -0.47 1.72 1.81 1.38
1926-12-31 5.14 2.59 2.30 3.37 1.96 4.23 2.22 2.40 -1.39 2.93 -1.38 6.39 2.59 3.06 2.17 2.18
Utils
1926-07-31 4.85
1926-08-31 -2.00
1926-09-30 2.06
1926-10-31 -2.98
1926-11-30 5.71
1926-12-31 1.72
我的目标是使用简单的投资组合选择规则进行回测。我想根据以下天真的规则分配权重,而不是持有等权重的投资组合:
- 为每项具有高于中值历史回报的资产分配权重 2/N
- 如果低于历史回报中值,则分配权重 0
代替等权向量:
w <- c(rep(1/17,17))
这个权重向量非常适合获得投资组合回报。为此,我使用了这个函数:
portfolio_returns_tq_rebl <-
returns %>%
tq_portfolio(assets_col = symbol,returns_col = return,weights = w,# here i want to have a weighting function?!
col_rename = "returns",rebalance_on = "months")
我坚持将加权函数合并到标准回测脚本(tidyquant、PerformanceAnalytics、quantmod)中。在其中大多数情况下,只能解决优化问题,而不能解决简单的天真的规则。
有人知道如何使用简单的投资组合选择规则进行这种回测吗?
感谢您的帮助!
解决方法
如果替代包也可以接受:这是我维护的如何使用 PMwR
的草图。我从一个示例数据集开始:来自 Kenneth French 网站的 17 个行业投资组合(可能与您使用的数据集相同)。
library("PMwR")
library("NMOF")
P <- French(tempdir(),"17_Industry_Portfolios_daily_CSV.zip",frequency = "daily",price.series = TRUE)
str(P)
## 'data.frame': 24935 obs. of 17 variables:
## $ Food : num 1 1 1 1 1.01 ...
## $ Mines: num 1 1 1.01 1 1 ...
## $ Oil : num 1 1.01 1.01 1.02 1.01 ...
## $ Clths: num 1 1 1 1 1.01 ...
## $ Durbl: num 1 0.989 0.983 0.965 0.964 ...
## $ Chems: num 1 1.01 1.02 1.02 1.03 ...
## $ Cnsum: num 1 1 1.01 1.01 1.01 ...
## $ Cnstr: num 1 1 1 1.01 1.01 ...
## $ Steel: num 1 0.994 1.006 1.007 1.007 ...
## $ FabPr: num 1 0.992 1.002 1.008 1.032 ...
## $ Machn: num 1 0.999 1.003 1.008 1.006 ...
## $ Cars : num 1 0.999 1.009 1.018 1.019 ...
## $ Trans: num 1 1 1 1 1 ...
## $ Utils: num 1 1.01 1.01 1.02 1.02 ...
## $ Rtail: num 1 1 1 0.998 0.992 ...
## $ Finan: num 1 1.01 1.01 1.01 1 ...
## $ Other: num 1 1 1 1.01 1.01 ...
可以使用函数 btest
运行回测。回测的主要“成分”是
在任何时刻调用并返回所需投资组合的“信号”函数。一个例子:这里的函数回顾 250 天,计算资产的收益,然后保留那些收益高于中值的资产。
above_median <- function() {
## get the most recent 250 days
H <- Close(n = 250)
## compute total return of industries
R <- H[nrow(H),] / H [1L,]
## include only those with an above-median return
include <- R > median(R)
w <- numeric(ncol(H))
w[include] <- 1/sum(include)
w
}
这个函数被传递给 btest
,并带有每季度调用它的指令。
bt <- btest(prices = list(as.matrix(P)),timestamp = as.Date(row.names(P)),signal = above_median,do.signal = "lastofquarter",b = 250,## burnin
initial.cash = 100,convert.weights = TRUE)
您可以分析结果。
summary(NAVseries(bt))
journal(bt)
更新,遵循以下评论:btest
不对数据频率施加限制。以下是月度数据示例,从月度回报开始。
P <- French(tempdir(),"17_Industry_Portfolios_CSV.zip",price.series = FALSE)
head(P) ## returns
## Food Mines Oil Clths Durbl Chems Cnsum Cnstr
## 1926-07-31 0.0048 0.0378 -0.0141 0.0602 -0.0162 0.0846 0.0142 0.0231
## 1926-08-31 0.0291 0.0069 0.0360 0.0015 -0.0196 0.0570 0.0584 0.0433
## ....
将收益转化为总收益序列:
P <- apply(P + 1,2,cumprod)
head(P) ## returns => 'prices'
## Food Mines Oil Clths Durbl Chems Cnsum
## 1926-07-31 1.004800 1.037800 0.9859000 1.060200 0.9838000 1.084600 1.014200
## 1926-08-31 1.034040 1.044961 1.0213924 1.061790 0.9645175 1.146422 1.073429
调整月度数据的信号函数:
above_median <- function() {
## get the most recent 12 months
H <- Close(n = 12)
## compute total return of industries
R <- H[nrow(H),]
## include only those with an above-median return
include <- R > median(R)
w <- numeric(ncol(H))
w[include] <- 1/sum(include)
w
}
使用适当的老化 b
运行回测。
bt <- btest(prices = list(as.matrix(P)),b = 12,convert.weights = TRUE)
unique(journal(bt)$timestamp) ## timestamps of trades
## [1] "1927-09-30" "1927-12-31" "1928-03-31" "1928-06-30" "1928-09-30"
## [6] "1928-12-31" "1929-03-31" "1929-06-30" "1929-09-30" "1929-12-31"
## ....