R语言与量化投资及凯利公式的应用(一)

凯利公式的诞生

1956年,在美国贝尔实验室工作的物理学家约翰·拉里·凯利为了解决长途电话信号传输中的噪声干扰问题1,提出了凯利公式。后来,凯利发现这个公式也同样适用于赌博和投资领域。该公式可以帮助投资者在长期重复博弈中通过优化每次投注的比例来最大化长期资本增长率,同时也有助于避免破产风险。

凯利在凯利公式的诞生中居功甚伟,但凯利公式在投资领域的大规模应用却归功于另一位金融大鳄,他就是在1987年史称“黑色星期一”大股灾中逆势获利的投资家爱德华·索普。

传奇人物爱德华·索普

爱德华·索普是举世闻名的金融大鳄,也是一位数学家。他同时也是投资书籍《战胜市场》(Beat the Market)和《战胜庄家》(Beat the Dealer)的作者。此人是坚定的量化投资派。他坚信金融市场上的行为可以通过数学模型和概率统计来描述和预测。他主张人们在金融市场上要基于数据进行投资决策,而不是凭借主观感觉。

在索普眼中,投资无非是一场“概率游戏”,人们可以通过对金融市场建立模型来捕捉金融市场的规律,并寻找在大数据意义上有显著优势的投资策略。

索普在投资中还格外注重资金的重要性,这一点和巴菲特不谋而合。他认为获取长期稳定投资收益的核心在控制单笔投资的风险,而不是追求单笔投资的最高汇报。因而,找到一种方式来确定单笔投资的投资比例就十分重要。

很久以来,索普并未思索出来确定投资比例的最佳数学方法,直到有一天他的至交好友信息学家香农告诉了他关于凯利和凯利公式的故事。他们两人一起利用凯利公式击败了拉斯维加斯赌场的庄家。好莱坞电影《决胜21点》讲述的正是他们的故事。

后来索普又将凯利公式加以扩展并运用到股票投资中,并在《战胜市场》一书中大肆推广。他倡导投资者们基于凯利公式来确定最优投资比例以平衡投资风险和收益,避免人们在投资过程中过于保守或者过度杠杆。

凯利公式的基本原理

假如我们正在玩一个纸牌游戏,在知悉游戏规则的情况下,我们清楚该游戏的胜率为 p ,对应的赔率为 b 。那么,我们该如何投注才能够使得我们在整个游戏中获得的资本增值最大呢?显然,这是一个数学问题。

我们可以假设初始资金为C_{0}游戏总共进行N轮,每次投注比例为f,获胜时资金将变为投资前的(1+bf)倍,失败时资金将变成1-f倍,进一步假设获胜次数为n_{1},那么失败次数为n_{2},且n=n_{1}+n_{2},那么,最终资金C_{n}可表示为:

C_{n}=C_{0}(1+bf)^{n_{1}}\cdot (1-f)^{n_{2}}

C_{n}取对数得:

lnC_{n}=lnC_{0}+n_{1}ln(1+bf)+n_{2}ln(1-f)

根据大数定律,当n足够大时,有:

n_{1}=pn
n_{2}=qn
q=1-p

于是:

lnC_{n}=lnC_{0}+npln(1+bf)+nqln(1-f)

lnC_{n}求导数并令导数为零。容易知道答案是:

f^*=\frac{p\cdot b-q}{b}

上式即为凯利公式。

用 R 语言模拟凯利公式

下面用最简单好用的R语言来模拟一下凯利公式的效果:

set.seed(97) #锁定随机种子,保证结果可重复
n <- 1000
p <- 0.52
b <- 1.05
initial_capital <- 10000

#计算凯利公式的投资比例
q <- 1-p
f_kelly <- (b*p-q)/b
f_half_kelly <- f_kelly/2
fixed_fraction <- 0.1

#模拟函数
simulate_kelly <- 
  function(fraction,initial_capital,n){
    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*b
      }
      else {
        capital[i+1] <- capital[i]-bet
      }
    }
   return(capital) 
  }

capital_kelly <-simulate_kelly(f_kelly,initial_capital,n)
capital_half_kelly <-simulate_kelly(f_half_kelly,initial_capital,n)
capital_fixed <- simulate_kelly(fixed_fraction,initial_capital,n)

# 创建数据框
df <- data.frame(
  step = 0:n,
  kelly = capital_kelly,
  half_kelly = capital_half_kelly,
  fixed = capital_fixed
)

# 转换为长格式
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",
    "固定比例:",fixed_fraction,"\n",
    "最终账户余额:\n",
    "全凯利策略:", format(round(capital_kelly[n+1], 2), big.mark = ","), "\n",
    "半凯利策略:", format(round(capital_half_kelly[n+1], 2), big.mark = ","), "\n",
    "固定策略:", format(round(capital_fixed[n+1], 2), big.mark = ","), "\n"
)
##  凯利公式比例: 0.0629 
##  半凯利比例: 0.0314 
##  固定比例: 0.1 
##  最终账户余额:
##  全凯利策略: 288,432.5 
##  半凯利策略: 69,690.41 
##  固定策略: 131,676.3

由上图可以直观的看出,在利用凯利公式下注的情况下,长期资本增值率完胜其他两种方式。


  1. 约翰·拉里·凯利,《噪声中信息率的新解释》
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容