长期投资的益处

长期投资的益处

本文为zonination/investing学习比较,作者以投资美国股市为例,通过图表的方式讲述了长期投资的益处,特别是投资达到 30、40 年时,资产将会稳健的大概率增长。

投资年限与收益乘子

首先是准备好数据集:stocks.csv,这份数据集包含了 1871-2016 年标普 500 指数的价格、股利以及消费者价格指数等月度变量。(S&P500 诞生于 1923 年,之前的数据来源于 Shiller)

1
2
3
4
5
6
7
8
setwd("~/Desktop/长期投资的益处")
library(ggplot2)
library(scales)
library(lubridate)
library(ggpomological)
theme_set(theme_pomological(base_size = 20, base_family = "MLingWaiMedium-SC") + theme(plot.title = element_text(hjust = 0.5)) + theme(plot.subtitle = element_text(hjust = 0.5)))
sp500 <- read.csv("stocks.csv", stringsAsFactors = F)
sp500$Date <- as.Date(sp500$Date, "%Y-%m-%d")

计算实际收益率(考虑年底股利再投资)

这里的计算公式是这样的:
$$
R_n = \frac{P_n + D_{n-1}/12}{P_{n-1}}
$$
这里,R 为月度实际收益率,P 为价格,D 为股利(年度)。

1
2
3
4
5
6
7
8
9
sp500$real.return <- 1
for(r in 2:nrow(sp500)){
sp500$real.return[r] <- sp500$real.return[r-1] *
(((sp500$Real.Price[r]-sp500$Real.Price[r-1]) /
(sp500$Real.Price[r-1])) + 1) +
(sp500$Real.Dividend[r-1]/sp500$Real.Price[r-1]) *
# 因为计算的是月份收益率,而股利是年度的,所以要除以12
(sp500$real.return[r-1]/12)
}

下面的代码有两个循环,第一个循环变量 f 从 0 个月遍历至 1745 个月(全部时间),表示投资的期限长度,第二个循环变量 n 从开始投资的那个(n-f)月份遍历至 1745 个月,然后计算每个投资时间段内的投资期限、总和收益率、收益率百分比变化、开始投资的期限。也就是:

  • year:投资期限;
  • real:实际收益率;
  • percent:收益变动百分比;
  • inv.date:开始投资的时间。

例如:
f = 10,n = 11 时表示从 n-f 即第 1 个月开始投资,投资 10 个月的情况;
f = 10,n = 12 时表示从 n-f 即第 2 个月开始投资,投资 10 个月······

由于我们投资的时间段是(n-f)到 n,所以投资期内实现的收益倍数是:
$$
R = \frac{P_n + D_{n-1}/12}{P_{n-f}}
$$

而:

$$
R_n = \frac{P_n + D_{n-1}/12}{P_{n-f}} \times R_{n-f}
$$

所以收益倍数为:

$$
R = \frac{R_n}{R_{n-f}}
$$

所以收益百分比为:

$$
R = \frac{R_n - R_{n-f}}{R_{n-f}}
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
stocks <- data.frame(NA, NA, NA, NA)
names(stocks) <- c("year", "real", "percent", "inv.date")
for(f in 0:nrow(sp500)){
sp500$future.f <- NA # 未来标普价格
sp500$cpi.f <- NA #未来CPI
sp500$future.r <- NA # 未来的实际收益率
buffer <- data.frame(NA, NA, NA, NA)
names(buffer) <- c("year", "real", "percent", "inv.date")
for(n in (f+1):nrow(sp500)){
# 得到f年后的价格
sp500$future.f[n-f] <- sp500$SP500[n]
# 得到f年后的CPI
sp500$cpi.f[n-f] <- sp500$Consumer.Price.Index[n]
# 得到f年后的实际收益率
sp500$future.r[n-f] <- sp500$real.return[n]
buffer <- rbind(buffer,
c(f/12,
sp500$real.return[n],
(sp500$real.return[n] - sp500$real.return[n-f]) /
sp500$real.return[n-f], as.character(sp500$Date[n-f])
)
)
}
stocks <- rbind(stocks, buffer)
print(paste(f, " of ", nrow(sp500), " completed: ", signif(f*100/nrow(sp500), 4), "%", sep = ""))
}
rm(buffer)
stocks<-subset(stocks,!is.na(stocks$percent))
# 把百分比收益转变成收益乘子
stocks$multip <- as.numeric(stocks$percent) + 1
stocks$year <- as.numeric(stocks$year)
stocks$real <- as.numeric(stocks$real)
stocks$percent <- as.numeric(stocks$percent)

然后,如果投资期限超过 40 年,那么如果你在任意一天入场(开始投资),那么随着你的投资期限的增加,你的资金增长路径如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 由于上面的计算过程过于耗时,所以为了安全期间,先把stocks保存成文件
library(io)
qwrite(stocks, "returns.rds")

p <- ggplot(subset(stocks, year < 40),
aes(x = year, y = multip), na.rm = T) +
geom_path(aes(group = inv.date),
alpha = 0.05, colour = "#fd8f24") +
stat_summary(fun.y = "mean", geom = "line",
colour = "#6b4525") +
labs(title = "图:投资后的收益率",
subtitle = "买入持有策略",
x = "在美国股市投资的年份(持有年份)",
y = "收益乘数") +
scale_x_continuous(breaks = seq(0, 200, 5)) +
scale_y_log10(breaks = 2^c(-3:15),
labels = as.character(2^c(-3:15)))

print(p)

还可以把这个图绘制的更复杂一些:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ggplot(subset(stocks, year < 40),
aes(x = year, y = multip), na.rm = T) +
geom_boxplot(outlier.shape = NA, coef = 0, fatten = 0, fill = "#a89985", colour = NA) +
geom_jitter(alpha = 0.05, aes(group = year)) +
geom_path(aes(group = inv.date),
alpha = 0.05, colour = "#fd8f24") +
geom_path(data = subset(stocks, inv.date == "1942-01-01" & year <= 50), aes(group = inv.date), colour = "black") +
stat_summary(fun.y = "mean", geom = "line",
colour = "#6b4525") +
labs(title = "图:投资后的收益率",
subtitle = "买入持有策略",
x = "在美国股市投资的年份(持有年份)",
y = "收益乘数") +
scale_x_continuous(breaks = seq(0, 200, 5)) +
scale_y_log10(breaks = 2^c(-3:15),
labels = as.character(2^c(-3:15))) +
scale_color_pomological()

图中黑色的路径表示从 1942 年 1 月开始投资的收益增长路径。

投资之后损失本金的概率

另外一个令我们关系的问题是,长期投资到多久才能几乎保证我的资金 100%的增长而不是损失呢?也就是说上图中的路径有多少拐到过 1 之下?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
stockrisk <- as.data.frame(matrix(NA, nrow = 31, ncol = 3))
names(stockrisk) <- c("year", "chance", "nochance")
for(n in 1:31){
stockrisk$chance[n] <-
length(subset(stocks, multip < 1 & year == n)$year)/length(subset(stocks, year == n)$year)
stockrisk$year[n] <- n
stockrisk$nochance <- 1 - stockrisk$chance[n]
}

ggplot(stockrisk, aes(year, chance)) +
geom_line() +
scale_y_continuous(labels = scales::percent_format()) +
ggtitle("图:在股市损失的概率") +
ylab("损失概率") +
xlab("投资年限") +
annotate("text", x = 20, y = 0.1, label = "在第20年的时候这一概率\n降为0.065%", family = "MLingWaiMedium-SC", size = 5) +
geom_segment(aes(x = 19, y = 0.08, xend = 20, yend = 0.0006), arrow = arrow(length = unit(0.5, "cm")), colour = "#fd8f24")

美国股市实际收益率的变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
for(f in 1:40){
sp500$future.f <- NA
sp500$cpi.f <- NA
sp500$future.r <- NA
for(n in (f*12 + 1):nrow(sp500)){
sp500$future.f[n - f*12] <- sp500$SP500[n]
sp500$cpi.f[n - f*12] <- sp500$Consumer.Price.Index[n]
sp500$future.r[n - f*12] <- sp500$real.return[n]
}
# 绘制标普500的资本利得
print(
ggplot(sp500, aes(Date,
(future.f - SP500)/(SP500))) +
geom_point(alpha = 0.5, colour = "#fd8f24", size = 3) +
ggtitle("图: 标普500资本利得") +
xlab("投资开始时间") +
ylab(paste("投资", f, "年后的收益")) +
geom_hline(yintercept = mean((sp500$future.f-sp500$SP500)/sp500$SP500, na.rm = T), linetype = 4) +
scale_y_continuous(limits = c(-5, 30), labels = percent_format()) +
geom_rug(sides = "r", size = 1, alpha = 0.2, colour = "#fd8f24")
)
if(f < 10){
ggsave(paste("geom_point0", f, ".png", sep = ""))
}
else{
ggsave(paste("geom_point", f, ".png", sep = ""))
}
print(paste("散点图", f, "绘制完毕!"))
# 绘制标普500的实际收益率
print(
ggplot(sp500, aes(Date,
future.r/real.return)) +
geom_point(alpha = 0.5, colour = "#fd8f24", size = 2) +
ggtitle("图:美国股市的实际收益率") +
xlab("开始是投资的时间") +
ylab(paste("投资", f, "年后的收益倍数")) +
geom_hline(yintercept =
mean(
sp500$future.r/sp500$real.return
, na.rm = T), linetype = 4, alpha = 0.3) +
scale_y_log10(limits = 2^c(-2, 6), breaks = 2^c(-3:15),
labels = as.character(2^c(-3:15))) +
geom_rug(sides = "r", size = 0.5, alpha = 0.1, colour = "#fd8f24")
)
if(f < 10){
ggsave(paste("geom_real0", f, ".png", sep = ""))
}
else{
ggsave(paste("geom_real", f, ".png", sep = ""))
}
print(paste("实际收益图", f, "绘制完成!"))

# 再绘制一个直方图
ggplot(sp500, aes((future.r - real.return)/real.return)) +
geom_vline(xintercept = mean(
(sp500$future.r - sp500$real.return)/sp500$real.return, na.rm = T
), linetype = 4, alpha = 0.3) +
geom_histogram(alpha = 0.5, fill = "#fd8f24") +
ggtitle("图:标普500实际收益率分布") +
xlab(paste("投资", f, "年之后的收益")) +
ylab(paste("出现频数")) +
scale_y_continuous(breaks = NULL) +
scale_x_continuous(limits = c(-2, 50), labels = percent_format())
if(f < 10){
ggsave(paste("geom_hist0", f, ".png", sep = ""))
}
else{
ggsave(paste("geom_hist", f, ".png", sep = ""))
}
print(paste("收益直方图", f, "绘制完成!"))
}

# 最后把这些图片转成GIF图
system("convert -delay 10 geom_real*.png 标普500实际收益率.gif")
system("convert -delay 10 geom_point*.png 标普500资本利得率.gif")
system("convert -delay 10 geom_hist*.png 标普500实际收益直方图.gif")
system("rm geom*.png")



可见,坚持长期投资可以取得相当可观稳定的收益!

# R

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×