在上篇文章R语言与量化投资及凯利公式的应用(一)中,我简单介绍了凯利公式的基本原理及其在投资中的应用,下面我们继续将凯利公式的扩展及其在证券投资中的应用方法。
凯利公式的扩展及其在股票投资中的利用
原始版本的凯利公式适用于赌博投注,因为它假设每次投注失败后下注者将完全失去下注的筹码。然而,人们在进行股票投资时,并非完全损失投资仓位,而只是损失了一部分比例。因此,如果想在股票投资中应该凯利公式,必须对凯利公式加以扩展。
凯利公式的扩展
假设我们已经掌握了一个投资策略,每次应用该投资策略时盈利的概率为,失败的概率为
;盈利时的净盈利率为
,失败时的净损失率为
;则盈利时资本金增加为
倍,失败时本金变为
倍。
如果我们的初始资本为,进行
次投资,投资成功次数为
,失败次数为
,那么,最总资金
可表示为:
对上式取对数,并利用大数定律可知:
对关于
求导,并令导函数为零,可得:
凯利公式在股票投资中的应用
熟悉蜡烛图形态分析的投资者应当知道,“早晨之星”是很常见的一个用来预示后续股市上涨的形态。我们可以利用 R 语言中的 candlesticks 包来甄别股票市场上满足“早晨之星”形态的股票,并将其纳入我们的投资组合。
以下是具体步骤和示例代码:
步骤 1:安装并加载包
install.packages("candlesticks") # 用于识别蜡烛图形态
install.packages("quantmod") # 用于获取股票数据
library(candlesticks)
library(quantmod)
步骤 2:获取股票数据
# 以苹果公司(AAPL)为例
getSymbols("AAPL", from = "2023-01-01")
head(AAPL)
步骤 3:识别射击之星形态
candlestick 包中提供了 CSPStar() 函数来用以识别“早晨之星”和“黄昏之星”。举例如下:
MorningStar <- CSPStar(AAPL)[,"MorningStar"]
head(MorningStar)
MorningStar
2020-01-02 NA
2020-01-03 NA
2020-01-06 FALSE
2020-01-07 FALSE
2020-01-08 FALSE
2020-01-09 FALSE
count <- sum(MorningStar[!is.na(MorningStar)])
cat("MorningStar出现的次数是:",count,"\n")
Date_MorningStar <- index(AAPL)[which(MorningStar[!is.na(MorningStar)]==TRUE)]
cat("MorningStar出现的时间是:",as.character(Date_MorningStar),"\n")
接下来我们来看一个常见的单一指标策略:假设我们在早晨之星形态出现当天以收盘价买入某支股票,盈利超过15%时止盈,亏损超过10%时止损,持有时间超过60个交易日止损。用 R 语言实现上述投资策略:
# 创建交易信号数据框
trades <- data.frame(
entry_date = as.Date(character()),
entry_price = numeric(),
exit_date = as.Date(character()),
exit_price = numeric(),
type = character()
)
# 遍历每个信号
for(i in which(MorningStar==1)) {
# 买入条件:当前为 Morning Star
entry_date <- index(AAPL)[i]
entry_price <- as.numeric(AAPL$Close[i])
# 寻找卖出条件(从次日开始)
for(j in (i+1):nrow(AAPL)) {
current_return <- as.numeric(AAPL$Close[j])/ entry_price - 1
# 条件1:收益率超过15%
if(current_return >= 0.15) {
trades <- rbind(trades, data.frame(
entry_date = entry_date,
entry_price = entry_price,
exit_date = index(AAPL)[j],
exit_price = as.numeric(AAPL$Close[j]),
type = "止盈"
))
break
}
# 条件2:收益率低于-10%
if(current_return <= -0.10) {
trades <- rbind(trades, data.frame(
entry_date = entry_date,
entry_price = entry_price,
exit_date = index(AAPL)[j],
exit_price = as.numeric(AAPL$Close[j]),
type = "止损"
))
break
}
# 条件3:持有60交易日
if(j - i == 60) {
trades <- rbind(trades, data.frame(
entry_date = entry_date,
entry_price = entry_price,
exit_date = index(AAPL)[j],
exit_price = as.numeric(AAPL$Close[j]),
type = "时间止损"
))
break
}
}
}
- 结果分析
# 计算总收益率
trades$returns <- (trades$exit_price / trades$entry_price) - 1
total_return <- sum(trades$returns)
cat("总收益率:", round(total_return*100, 2), "%\n")
cat('胜率:', round(sum(trades$returns>0)/length(trades$returns)*100,2),"%\n")
cat('单笔盈利:',round(total_return/length(trades$returns),2),"%\n")
# 查看交易记录
print(trades)
总收益率: 65.31 %
胜率: 64.29 %
单笔盈利: 0.05 %
entry_date entry_price exit_date exit_price type returns
1 2020-03-24 61.72 2020-04-14 71.7625 止盈 0.16271056
2 2020-11-11 119.49 2021-01-22 139.0700 止盈 0.16386317
3 2021-03-22 123.39 2021-06-16 130.1500 时间止损 0.05478559
4 2021-10-14 143.76 2021-12-07 171.1800 止盈 0.19073455
5 2021-12-15 179.30 2022-01-25 159.7800 止损 -0.10886784
6 2022-03-09 162.95 2022-05-11 146.5000 止损 -0.10095120
7 2022-04-04 178.44 2022-04-26 156.8000 止损 -0.12127325
8 2022-04-28 163.64 2022-05-11 146.5000 止损 -0.10474211
9 2022-09-19 154.48 2022-09-30 138.2000 止损 -0.10538581
10 2022-12-21 135.45 2023-03-16 155.8500 止盈 0.15060915
11 2023-04-27 168.41 2023-06-30 193.9700 止盈 0.15177244
12 2023-05-05 173.57 2023-08-02 192.5800 时间止损 0.10952350
13 2023-08-14 179.46 2023-11-07 181.8200 时间止损 0.01315057
14 2024-05-02 173.03 2024-06-11 207.1500 止盈 0.19719121
上述策略的胜率等于0.6531,
等于0.1327,
等于0.1082。根据扩展后的凯利公式可计算出最佳投资比例为:
基于上述策略参数,用 R 模拟长期投资结果:
set.seed(97) #锁定随机种子,保证结果可重复
n <- 1000
p <- 0.6531 #早晨之星的历史胜率
r_w <- 0.1327 #早晨之星的历史盈利率均值
r_l <- 0.1082 #早晨之星的历史损失率均值
initial_capital <- 10000
#计算凯利公式的投资比例
q <- 1-p
f_kelly <- (p*r_w-q*r_l)/r_w*r_l
f_half_kelly <- f_kelly/2
#模拟函数
simulate_kelly <- function(fraction,initial_capital,n,p){
capital <- rep(initial_capital,n+1)
for (i in 1:n){
bet <- capital[i]*fraction
outcome <- rbinom(1,1,p)
if(outcome == 1){
capital[i+1] <- capital[i]+bet*r_w
}
else {
capital[i+1] <- capital[i]-bet*r_l
}
}
return(capital)
}
capital_kelly <-simulate_kelly(f_kelly,initial_capital,n,p)
capital_half_kelly <-simulate_kelly(f_half_kelly,initial_capital,n,p)
# 创建数据框
df <- data.frame(
step = 0:n,
kelly = capital_kelly,
half_kelly = capital_half_kelly
)
# 转换为长格式
df_long <- reshape2::melt(df, id.vars = "step")
为了直观感受凯利公式的效果,可以绘制一幅简单的线图。
library(ggplot2)
ggplot(df_long, aes(x = step, y = value, color = variable)) +
geom_line(linewidth = 0.5) +
scale_y_log10() +
labs(
title = "simulate the result of three bet strategy",
subtitle = paste("Win_rate p=", p," Odds b=", b, " Number_of_Trans=", n),
x = "Numbers_of_Transaction",
y = "Appreciated_amount(log)",
color = "strategy"
) +
theme_minimal() +
theme(legend.position = "bottom",
plot.title = element_text(hjust=0.5),
plot.subtitle = element_text(hjust=0.5)
)
image.png
查看一下上述策略对应的投资结果:
# 输出最终结果
cat(" 凯利公式比例:", round(f_kelly, 4), "\n",
"半凯利比例:", round(f_half_kelly, 4), "\n",
"最终账户余额:\n",
"全凯利策略:", format(round(capital_kelly[n+1], 2), big.mark = ","), "\n",
"半凯利策略:", format(round(capital_half_kelly[n+1], 2), big.mark = ","), "\n"
)
## 凯利公式比例: 0.0401
## 半凯利比例: 0.02
## 最终账户余额:
## 全凯利策略: 76,292.89
## 半凯利策略: 27,178.01








网友评论