如何在投资组合绩效图中仅选择有效的前沿点?
How to pick only efficient frontier points in a plot of portfolio performance?
这个问题的名称并不公平。这最好通过数值示例来解释。假设我有以下投资组合数据,称为 data
.
> data
Stdev AvgReturn
1 1.92 0.35
2 1.53 0.34
3 1.39 0.31
4 1.74 0.31
5 1.16 0.30
6 1.27 0.29
7 1.78 0.28
8 1.59 0.27
9 1.05 0.27
10 1.17 0.26
11 1.62 0.25
12 1.33 0.25
13 0.96 0.24
14 1.47 0.24
15 1.09 0.24
16 1.20 0.24
17 1.49 0.23
18 1.01 0.23
19 0.88 0.22
20 1.21 0.22
21 1.37 0.22
22 1.09 0.22
23 0.95 0.21
24 0.81 0.21
我已经按 AvgReturn
对 data
data.frame 进行了排序(我认为这样更容易)。我的目风险衡量标准,但我现在假设是这样)。
本质上,有没有人知道一种有效的(在代码意义上)选择 "rational" 投资组合的方法。我已经为此数据框手动创建了第三列,以向您展示应保留哪些投资组合选择。我想删除投资组合 4,因为我永远不会选择它,因为我可以选择投资组合 3 并获得相同的 return 和更低的标准偏差。同样,我永远不会选择 8,因为我可以选择更高 return 和更低标准偏差的 5。
> res
Stdev AvgReturn Keep
1 1.92 0.35 TRUE
2 1.53 0.34 TRUE
3 1.39 0.31 TRUE
4 1.74 0.31 FALSE
5 1.16 0.30 TRUE
6 1.27 0.29 FALSE
7 1.78 0.28 FALSE
8 1.59 0.27 FALSE
9 1.05 0.27 TRUE
10 1.17 0.26 FALSE
11 1.62 0.25 FALSE
12 1.33 0.25 FALSE
13 0.96 0.24 TRUE
14 1.47 0.24 FALSE
15 1.09 0.24 FALSE
16 1.20 0.24 FALSE
17 1.49 0.23 FALSE
18 1.01 0.23 FALSE
19 0.88 0.22 TRUE
20 1.21 0.22 FALSE
21 1.37 0.22 FALSE
22 1.09 0.22 FALSE
23 0.95 0.21 FALSE
24 0.81 0.21 TRUE
我能想到的解决这个问题的唯一方法是遍历并检查每个条件。但是,这在 R
我对此解决方案的首选语言中效率相对较低。我很难想到矢量化解决方案。感谢您的帮助!
编辑
我认为这是一个解决方案:
domstrat <- function(data){
keep <- c(-1,sign(diff(cummin(data[[1]]))))
data <- data[which(keep!=0),]
return(data)
}
Stdev AvgReturn
1 1.92 0.35
2 1.53 0.34
3 1.39 0.31
5 1.16 0.30
9 1.05 0.27
13 0.96 0.24
19 0.88 0.22
24 0.81 0.21
您可以定义一个自定义 R function
,其中包含一些逻辑来根据标准差和平均值决定是否保留某个投资组合 return:
>portfolioKeep <- function(x){
+ # x[1] contains the Stdev for the input row
+ # x[2] contains the AvgReturn for the input row
+ # make your decision based on these inputs here...
+ # and remember to return either "TRUE" or "FALSE"
+ }
接下来我们可以在您的输入数据框上使用 apply
函数来得出您想要的 Keep
列:
# your 'input' data frame
input.mat <- data.matrix(input)
# apply custom function to rows
keep <- apply(input.mat, 1, portfolioKeep)
# bind keep vector to input data frame
input <- cbind(input, keep)
上面的代码首先将input
数据框转换为数值矩阵,这样我们就可以在其上使用apply
函数了。 apply
函数将在每一行上 运行 portfolioKeep
,returning "TRUE" 或 "FALSE." 最后,我们滚动 Keep
为方便起见,向上列到原始数据框中。
现在您可以使用开始时使用的数据框 input
轻松地进行报告。
这使用函数 cummax
通过对原始数据进行测试来确定一系列合格点:
> data <- data[order(data$Stdev),]
> data[ which(data$AvgReturn == cummax(data$AvgReturn)) , ]
Stdev AvgReturn
24 0.81 0.21
19 0.88 0.22
13 0.96 0.24
9 1.05 0.27
5 1.16 0.30
3 1.39 0.31
2 1.53 0.34
1 1.92 0.35
> plot(data)
> points( data[ which(data$AvgReturn == cummax(data$AvgReturn)) , ] , col="green")
它实际上不是凸包,而是所谓的 "monotonically increasing hull"。
这个问题的名称并不公平。这最好通过数值示例来解释。假设我有以下投资组合数据,称为 data
.
> data
Stdev AvgReturn
1 1.92 0.35
2 1.53 0.34
3 1.39 0.31
4 1.74 0.31
5 1.16 0.30
6 1.27 0.29
7 1.78 0.28
8 1.59 0.27
9 1.05 0.27
10 1.17 0.26
11 1.62 0.25
12 1.33 0.25
13 0.96 0.24
14 1.47 0.24
15 1.09 0.24
16 1.20 0.24
17 1.49 0.23
18 1.01 0.23
19 0.88 0.22
20 1.21 0.22
21 1.37 0.22
22 1.09 0.22
23 0.95 0.21
24 0.81 0.21
我已经按 AvgReturn
对 data
data.frame 进行了排序(我认为这样更容易)。我的目风险衡量标准,但我现在假设是这样)。
本质上,有没有人知道一种有效的(在代码意义上)选择 "rational" 投资组合的方法。我已经为此数据框手动创建了第三列,以向您展示应保留哪些投资组合选择。我想删除投资组合 4,因为我永远不会选择它,因为我可以选择投资组合 3 并获得相同的 return 和更低的标准偏差。同样,我永远不会选择 8,因为我可以选择更高 return 和更低标准偏差的 5。
> res
Stdev AvgReturn Keep
1 1.92 0.35 TRUE
2 1.53 0.34 TRUE
3 1.39 0.31 TRUE
4 1.74 0.31 FALSE
5 1.16 0.30 TRUE
6 1.27 0.29 FALSE
7 1.78 0.28 FALSE
8 1.59 0.27 FALSE
9 1.05 0.27 TRUE
10 1.17 0.26 FALSE
11 1.62 0.25 FALSE
12 1.33 0.25 FALSE
13 0.96 0.24 TRUE
14 1.47 0.24 FALSE
15 1.09 0.24 FALSE
16 1.20 0.24 FALSE
17 1.49 0.23 FALSE
18 1.01 0.23 FALSE
19 0.88 0.22 TRUE
20 1.21 0.22 FALSE
21 1.37 0.22 FALSE
22 1.09 0.22 FALSE
23 0.95 0.21 FALSE
24 0.81 0.21 TRUE
我能想到的解决这个问题的唯一方法是遍历并检查每个条件。但是,这在 R
我对此解决方案的首选语言中效率相对较低。我很难想到矢量化解决方案。感谢您的帮助!
编辑 我认为这是一个解决方案:
domstrat <- function(data){
keep <- c(-1,sign(diff(cummin(data[[1]]))))
data <- data[which(keep!=0),]
return(data)
}
Stdev AvgReturn
1 1.92 0.35
2 1.53 0.34
3 1.39 0.31
5 1.16 0.30
9 1.05 0.27
13 0.96 0.24
19 0.88 0.22
24 0.81 0.21
您可以定义一个自定义 R function
,其中包含一些逻辑来根据标准差和平均值决定是否保留某个投资组合 return:
>portfolioKeep <- function(x){
+ # x[1] contains the Stdev for the input row
+ # x[2] contains the AvgReturn for the input row
+ # make your decision based on these inputs here...
+ # and remember to return either "TRUE" or "FALSE"
+ }
接下来我们可以在您的输入数据框上使用 apply
函数来得出您想要的 Keep
列:
# your 'input' data frame
input.mat <- data.matrix(input)
# apply custom function to rows
keep <- apply(input.mat, 1, portfolioKeep)
# bind keep vector to input data frame
input <- cbind(input, keep)
上面的代码首先将input
数据框转换为数值矩阵,这样我们就可以在其上使用apply
函数了。 apply
函数将在每一行上 运行 portfolioKeep
,returning "TRUE" 或 "FALSE." 最后,我们滚动 Keep
为方便起见,向上列到原始数据框中。
现在您可以使用开始时使用的数据框 input
轻松地进行报告。
这使用函数 cummax
通过对原始数据进行测试来确定一系列合格点:
> data <- data[order(data$Stdev),]
> data[ which(data$AvgReturn == cummax(data$AvgReturn)) , ]
Stdev AvgReturn
24 0.81 0.21
19 0.88 0.22
13 0.96 0.24
9 1.05 0.27
5 1.16 0.30
3 1.39 0.31
2 1.53 0.34
1 1.92 0.35
> plot(data)
> points( data[ which(data$AvgReturn == cummax(data$AvgReturn)) , ] , col="green")
它实际上不是凸包,而是所谓的 "monotonically increasing hull"。