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

说明

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

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

问题描述

假想一个游戏。赢的概率是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()

效果图

结论

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

posted @ 2017-07-25 09:26  罗兵  阅读(1296)  评论(0编辑  收藏  举报