如何在R中的一个图中计算/绘制每个时间段的有效边界?

时间:2017-12-03 14:31:00

标签: r

目前我们计算和排序股票数据(X1到X10)。历史数据存储在Excel和R中,时间为1950-1980,1980-1999和1950-1999。

数据集:

       date     X1      X2    X3    X4    X5     X6   X7    X8    X9   X10
1   1950-01-01  5.92   6.35  4.61  4.08  5.47  3.90  2.35  1.49  2.27  0.82
2   1950-02-01  2.43   2.16  2.10  1.58 -0.05  1.14  1.51  1.52  2.02  1.12
3   1950-03-01 -0.81   0.21 -1.67 -0.02 -0.79  0.18 -0.22  1.03  0.12  1.75
4   1950-04-01  5.68   6.45  5.41  5.94  6.10  5.87  3.82  3.34  3.44  3.97
5   1950-05-01  3.84   1.60  1.64  3.33  2.54  2.12  4.46  2.83  3.82  4.75
6   1950-06-01 -9.88 -10.56 -8.02 -7.86 -7.27 -7.44 -7.13 -7.76 -6.32 -5.04
7   1950-07-01  9.09   8.76  7.31  5.88  3.84  4.61  3.09  3.07  1.41  0.42
598 1999-10-01 -0.95  -1.88 -1.25 -0.52  1.65  0.72  5.41  4.38  5.58  6.59
599 1999-11-01 11.57   9.15  8.17  7.14  6.15  4.95  5.78  4.21  1.55  2.15
600 1999-12-01 12.32  14.97  9.29 11.77 11.09  5.89 11.88 11.26  6.23  5.64

主要问题是,我们希望计算/绘制这4个时间段的有效边界,以了解有效边界如何在1个图中演变。有没有办法在R?

中做到这一点

有效前沿是一组最优投资组合,它为定义的风险水平提供最高的预期回报,或者为给定的预期回报水平提供最低风险。

在现代投资组合理论中,有效前沿(或投资组合前沿)是一种投资组合,它占据了“高效”的投资组合。风险回报范围的一部分。从形式上看,它是一组投资组合,它满足条件,即没有其他投资组合存在较高的预期收益但具有相同的收益标准差。

那么,如何在R中计算这个呢?

输入样本数据(前50行)

> dput(head(data,50))

structure(list(X__1 = structure(c(-631152000, -628473600, -626054400, 
-623376000, -620784000, -618105600, -615513600, -612835200, -610156800, 
-607564800, -604886400, -602294400, -599616000, -596937600, -594518400, 
-591840000, -589248000, -586569600, -583977600, -581299200, -578620800, 
-576028800, -573350400, -570758400, -568080000, -565401600, -562896000, 
-560217600, -557625600, -554947200, -552355200, -549676800, -546998400, 
-544406400, -541728000, -539136000, -536457600, -533779200, -531360000, 
-528681600, -526089600, -523411200, -520819200, -518140800, -515462400, 
-512870400, -510192000, -507600000, -504921600, -502243200), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), X__2 = c(5.92, 2.43, -0.81, 5.68, 
3.84, -9.88, 9.09, 4.93, 3.99, -0.5, 3.09, 15.77, 8.22, 0.36, 
-7.36, 3.84, -2.81, -7.12, 3.57, 6.59, 1.04, -1.41, -1.42, -0.53, 
1.86, -3.25, 0.68, -4.4, 0.57, 2.5, -0.36, -0.74, -1.11, -0.58, 
3.22, 0.33, 5.01, 2.75, -1.25, -2.13, 1.3, -4.42, 0.25, -5.56, 
-4.09, 2.71, 2.01, -3.15, 8.48, -0.16), X__3 = c(6.35, 2.16, 
0.21, 6.45, 1.6, -10.56, 8.76, 4.63, 3.52, -1.2, 3.36, 10.98, 
8.41, 0.81, -4.01, 3.56, -4.27, -6.11, 4.7, 5.3, 2.73, -3.07, 
-0.13, 0.6, 1.1, -2.77, 2.37, -4.5, 1.87, 3.18, 1.51, 0.43, -1.91, 
-1.52, 4.91, 1.43, 3.4, 3.03, -2.25, -2, 0.34, -4.75, 2.24, -6.53, 
-1.87, 1.97, 1.78, -2.96, 7.38, 0.43), X__4 = c(4.61, 2.1, -1.67, 
5.41, 1.64, -8.02, 7.31, 4.56, 5.18, -0.46, 3.52, 10.78, 8.46, 
0.28, -4.88, 4.26, -3.25, -6.76, 6.78, 4.99, 3.86, -2.57, 0.59, 
0.16, 1.75, -2.04, 2.49, -5.29, 1.76, 2.88, 0.76, 0.67, -1.67, 
-1.45, 5.69, 2.95, 3.66, 1.15, -1.58, -2.34, 0.51, -3.82, 0.72, 
-6.25, -2.33, 3.1, 2.19, -2.63, 7.3, 1.82), X__5 = c(4.08, 1.58, 
-0.02, 5.94, 3.33, -7.86, 5.88, 4.68, 5.99, 0.75, 2.68, 9.29, 
8, 1.08, -3.13, 4.21, -3.35, -5.01, 5.77, 4.85, 2.73, -3.44, 
0.27, 1.56, 1.62, -2.35, 2.93, -4.62, 2.36, 2.56, 0.86, 0.16, 
-1.8, -2.04, 5.12, 2.72, 3.21, 1.21, -2.17, -1.84, 0.32, -3.63, 
1.47, -5.16, -0.65, 3.33, 1.34, -1.36, 6.24, 1.19), X__6 = c(5.47, 
-0.05, -0.79, 6.1, 2.54, -7.27, 3.84, 6.29, 4.46, -0.24, 2.42, 
6.12, 8.63, 0.88, -3.31, 4.56, -2.14, -5.62, 5.73, 5.36, 2.44, 
-1.88, 0.83, 0.65, 1.47, -1.81, 2.31, -4.48, 2.56, 2.69, 0.9, 
0.34, -0.62, -1.58, 6.59, 0.86, 3.58, 1.92, -1.85, -2.79, 0.7, 
-3.4, 1.26, -5.26, -1.18, 4.26, 1.35, -0.97, 6.66, 1.77), X__7 = c(3.9, 
1.14, 0.18, 5.87, 2.12, -7.44, 4.61, 4.57, 6.14, -0.84, 4.22, 
8.37, 7.44, 0.69, -4.26, 4.13, -2.24, -6.75, 5.81, 4.35, 1.98, 
-2.87, 0.93, 0.61, 1.27, -2.18, 2.97, -4.09, 2.27, 2.96, 1.16, 
-0.38, -2.37, -0.71, 5.53, 2.45, 1.3, 0.31, -0.47, -2.03, 0.14, 
-3.26, 1.79, -5.5, -1.47, 4.18, 1.96, -1.35, 7.06, 1.69), X__8 = c(2.35, 
1.51, -0.22, 3.82, 4.46, -7.13, 3.09, 5.01, 5.84, -1.05, 3.81, 
7.54, 6.46, 0.71, -3.56, 4.42, -1.87, -4.52, 7.3, 3.66, 2.11, 
-2.92, 2.25, 2.17, 1.32, -1.71, 3.17, -4.63, 2.59, 3.89, 0.49, 
0.21, -1.71, -1.18, 4.95, 3.21, 1.41, 0.89, -1.02, -2.89, 0.59, 
-2.67, 1.47, -4.62, -0.69, 4.07, 2.83, -1.44, 6.11, 1.58), X__9 = c(1.49, 
1.52, 1.03, 3.34, 2.83, -7.76, 3.07, 3.72, 6.21, -1.66, 3.46, 
6.14, 7.17, 2.13, -3.19, 4.59, -2.65, -3.5, 7.43, 3.5, 2.41, 
-2.73, 1.35, 1.97, 1.72, -1.8, 4.06, -5.35, 2.57, 3.14, 1.89, 
-0.86, -1.73, -0.95, 6.07, 1.73, 1.09, 0.37, -1.34, -2.48, 0.31, 
-3.2, 1.34, -4.99, -0.18, 4.35, 3.03, 0.09, 5.65, 2.39), X__10 = c(2.27, 
2.02, 0.12, 3.44, 3.82, -6.32, 1.41, 4.54, 5.55, -0.97, 3.8, 
5.69, 5.65, 1.78, -2.6, 4.21, -1.29, -2.63, 7.15, 3.52, 1.85, 
-2.32, 0.96, 2.74, 1.9, -2.6, 3.83, -4.31, 3.15, 2.76, 0.93, 
-0.39, -1.86, -1.57, 7.05, 2.36, -0.33, -0.23, -0.54, -2.6, 0.61, 
-2.37, 2.12, -3.76, 0.47, 3.98, 3.03, 0.2, 5.63, 1.26), X__11 = c(0.82, 
1.12, 1.75, 3.97, 4.75, -5.04, 0.42, 4.96, 4.32, 0.25, 2.26, 
4.71, 5.05, 1.63, -1.53, 5.12, -2.59, -1.92, 6.89, 4.48, -0.09, 
-2.49, 0.26, 4.03, 1.37, -2.82, 4.95, -5.1, 3.4, 4.29, 0.89, 
-1.06, -2.18, -0.31, 5.76, 3.32, -1.04, -0.63, -1.78, -2.97, 
0.55, -1.3, 2.75, -4.47, 0.48, 4.83, 2.85, 0.27, 4.4, 1.93)), .Names = c("date", 
"X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", 
"X9", "X10"), row.names = c(NA, 50L), class = c("tbl_df", 
"tbl", "data.frame"))

1 个答案:

答案 0 :(得分:0)

经过与@Jonathan的评论之后的一些相应性,我通过一些采样将示例数据从3列扩展到12列。而且the blog的“随卖空”部分的代码可以很好地扩展到10K的观察结果:

# using code at:
# https://www.r-bloggers.com/a-gentle-introduction-to-finance-using-r-efficient-frontier-and-capm-part-1/
# https://datashenanigan.wordpress.com/2016/05/24/a-gentle-introduction-to-finance-using-r-efficient-frontier-and-capm-part-1/

library(data.table)

calcEFParams <- function(rets)
{

    retbar <- colMeans(rets, na.rm = T)
    covs <- var(rets, na.rm = T) # calculates the covariance of the returns
    invS <- solve(covs)
    i <- matrix(1, nrow = length(retbar))

    alpha <- t(i) %*% invS %*% i
    beta <- t(i) %*% invS %*% retbar
    gamma <- t(retbar) %*% invS %*% retbar
    delta <- alpha * gamma - beta * beta

    retlist <- list(alpha = as.numeric(alpha),
                    beta = as.numeric(beta),
                    gamma = as.numeric(gamma),
                    delta = as.numeric(delta))

    return(retlist)
}

# load data
link <- "https://raw.githubusercontent.com/DavZim/Efficient_Frontier/master/data/mult_assets.csv"

df <- data.table(read.csv(link))
df2 <- df[,lapply(.SD, sample),]
df3 <- cbind(df, df2)
df4 <- df3[,lapply(.SD, sample),]
df5 <- cbind(df3, df4)

现在加载microbenchmark软件包,性能就是这样:

> library(microbenchmark)
> microbenchmark(calcEFParams(df5), times = 10)
Unit: milliseconds
              expr      min       lq     mean   median       uq      max neval
 calcEFParams(df5) 2.692514 2.764053 2.795127 2.777547 2.805447 3.024349    10

似乎David Zimmermann的代码可扩展且足够高效!