蒙特卡罗方法验证凯利公式

说明

本文受知乎陈小米启发而写。有兴趣的朋友可以移步这里

本文的代码完全是本人所撸。

问题描述

假想一个游戏。赢的概率是60%,输的概率40%。入场费随意交。如果赢了获得2倍的入场费金额(1赔1),输则输掉入场费。小米有1000元做本金,请问小米每次给多少入场费,理论上100次游戏后几何期望收益能最大?

【本人的疑问】为何这里考虑几何期望,而不是数学期望?【已解决,见代码注释!】

凯利公式

\[f=p-\frac{q}{b}\]

不多说,上代码。

完整代码

import pandas as pd
import numpy as np
import random
import matplotlib.pyplot as plt

'''
用蒙特卡罗方法,验证凯利公式的计算得到资金比例是不是最佳的

参考:https://zhuanlan.zhihu.com/p/20849995
'''

pwin = 0.6  # 胜率
b = 1       # 净赔率

# 凯利值
def kelly(pwin, b):
    '''
    参数
        pwin 胜率
        b    净赔率
    返回
        f    投注资金比例
    '''
    f = (b * pwin + pwin - 1) / b
    return f

# 游戏
def play_game(f, cash=100, m=100):
    global pwin, b

    res = [cash]
    for i in range(m):
        if random.random() <= pwin:
            res.append(res[-1] + int(f*res[-1])*b)
        else:
            res.append(res[-1] - int(f*res[-1]))
    return res

# 蒙特卡罗方法重复玩游戏
def montecarlo(n=1000, f=0.15, cash=1000, m=100):
    res = []

    for i in range(n):
        res.append(play_game(f, cash, m))

    #return pd.DataFrame(res).sum(axis=0) / n   #【 数学期望】不平滑
    return np.exp(np.log(pd.DataFrame(res)).sum(axis=0) / n) # 【几何期望】平滑

n = 1000       # 重复次数
cash = 1000 # 初始资金池
m = 100        # 期数

f = 0.1 # 资金比例 10%
res1 = montecarlo(n, f, cash, m)

fk = kelly(pwin, b)  # 资金比例 凯利值
res2 = montecarlo(n, fk, cash, m)

f = 0.5 # 资金比例 50%
res3 = montecarlo(n, f, cash, m)

f = 1.0 # 资金比例 100%
res4 = montecarlo(n, f, cash, m)

# 画个图看看
fig = plt.figure()
axes = fig.add_subplot(111)

axes.plot(res1,'r-',label='10%')
axes.plot(res2,'g*',label='{:.1%}'.format(fk))
axes.plot(res3,'b-',label='50%')
axes.plot(res4,'k-',label='100%')
plt.legend(loc = 0)

plt.show()

效果图

结论

由图显见,凯利值是最优的。

时间: 2024-08-29 06:46:28

蒙特卡罗方法验证凯利公式的相关文章

凯利公式的模拟验证

凯利公式的模拟验证 场景:一个赌局,你跟庄家.你出 1 元,庄家出 0.96元.赌金数目可随之翻倍.    根据每次抛色子的结果的单双决定胜负.    胜者得到双方所下的赌金,计 1.96 元.   问题:如何下注才能做到,风险最小,盈利最大呢?   答案:凯利公式. 凯利公式的作用: 根据赔率与胜率,得出你每次的资金下注比例   公式的形式: 1 + 赔率 - 1/胜率   凯利公式最初为 AT&T 贝尔实验室物理学家约翰·拉里·凯利根据同僚克劳德·艾尔伍德·香农於长途电话线杂讯上的研究所建立

蒙特卡罗方法入门

本文通过五个例子,介绍蒙特卡罗方法(Monte Carlo Method). 一.概述 蒙特卡罗方法是一种计算方法.原理是通过大量随机样本,去了解一个系统,进而得到所要计算的值. 它非常强大和灵活,又相当简单易懂,很容易实现.对于许多问题来说,它往往是最简单的计算方法,有时甚至是唯一可行的方法. 它诞生于上个世纪40年代美国的"曼哈顿计划",名字来源于赌城蒙特卡罗,象征概率. 二.π的计算 第一个例子是,如何用蒙特卡罗方法计算圆周率π. 正方形内部有一个相切的圆,它们的面积之比是π/4

《深度学习导论及案例分析》一2.12马尔可夫链蒙特卡罗方法

2.12马尔可夫链蒙特卡罗方法 在统计学中,马尔可夫链蒙特卡罗方法是一类根据概率分布进行采样的方法,起源于物理学科[133].这类方法以构造一个马尔可夫链为基础,其期望分布(desired distribution)就是平衡分布(equilibrium distribution).极限分布(limiting distribution)或稳态分布(stationary disrtibution).经过若干步骤之后,马尔可夫链的状态便被用作期望分布的一个样本.样本的质量随着步骤数目的增加而不断提高,

PHP自带方法验证邮箱、URL、IP是否合法的函数_php技巧

以前用PHP验证邮箱.URL.IP是否合法都是通过自己写正则来实现,但是有时候脑子发昏,可能会写出一个不是完全正确的正则,导致验证出错,今天发现原来PHP本身自带了验证邮箱.URL.IP是否合法的函数. 主要使用的是filter_var函数. 语法 filter_var(variable, filter, options) 参数 描述 variable 必需.规定要过滤的变量. filter 可选.规定要使用的过滤器的 ID. options 规定包含标志/选项的数组.检查每个过滤器可能的标志和

蒙特卡罗方法 python 实现

蒙特卡罗(Monte Carlo)方法的精髓:用统计结果去计算频率,从而得到真实值的近似值. 一.求圆周率的近似值,采用 投点法 import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Circle # 投点次数 n = 10000 # 圆的信息 r = 1.0 # 半径 a, b = (0., 0.) # 圆心 # 正方形区域边界 x_min, x_max = a-r, a+r y_mi

蒙特卡罗方法 python 实现2

如果不考虑作图,这里的两个例子可以改写成下面的样子: 求圆周率 import random ''' 蒙特卡罗模拟 投点法计算圆周率 ''' # 投点游戏 def play_game(): # 圆 r = 1.0 # 半径 a, b = (0., 0.) # 圆心 # 正方形区域边界 x_min, x_max = a-r, a+r y_min, y_max = b-r, b+r # 在 正方形 区域内随机投点 x = random.uniform(x_min, x_max) # 均匀分布 y =

Struts2教程4:使用validate方法验证数据

在Struts2中最简单的验证数据的方法是使用validate.我们从ActionSupport类的源代码中可以看到,ActionSupport类实现了一个Validateable接口.这个接口只有一个validate方法.如果Action类实现了这个接口,Struts2在调用execute方法之前首先会调用这个方法,我们可以在validate方法中验证,如果发生错误,可以根据错误的level选择字段级错误,还是动作级错误.并且可使用addFieldError或addActionError加入相

通过分析设计的方法验证UED价值

首先说明一点,本文中提到的UED基本都指交互设计. 一.为什么需要数据验证? "天天看到你们也挺忙的,但是怎么衡量游戏用户体验提升了多少." 是的,高层对战略方向关注的更多,不可能了解每个员工所有的工作细节,尤其是我们是做用户体验的.在最终的游戏体验里,能看到漂亮的视觉.有趣 的玩法,却唯独感觉不到交互多美妙.其实交互设计的追求恰恰是"让用户感觉不到界面的存在",只有感觉不到界面的存在,才能沉浸在游戏里,感受身临其境的 愉悦,感受玩法的趣味. 对于大多数公司来说,高

PHP自带方法验证邮箱是否存在_php技巧

PHP校验邮箱地址的方法很多, 比较常用的就是自己写正则了, 不过正则多麻烦, 我PHP自带了方法做校验. filter_var filter_var是PHP内置的一个变量过滤的方法, 提供了很多实用的过滤器, 可以用来校验整数.浮点数.邮箱.URL.MAC地址等. filter_var如果返回false, 说明变量无法通过过滤器, 也就是不合法了. $email = "lastchiliarch@163.com"; var_dump(filter_var($email, FILTER