カジノなどで用いられる、ベッティングシステムのシミュレーション

##初めに

###ベッティングシステムの概要
wikipediaによるとベッティングシステムの定義は次のようになっている。
>ベッティングシステム (Betting system) とは、カジノなどの賭博で、どのような賭け方（ベット）をするかの戦略である。ベッティングストラテジ (Betting strategy)、マネーマネジメント (Money management) とも呼ばれる。

###今回行ったシミュレーション
今回はこのベッティングシステムを用いてカジノのルーレットで勝てるかpython3シミュレーションしました。

今回使用したベッティングシステムはマーチンゲール法、逆マーチンゲール法(パーレ法)ダランベール法、イーストコーストプログレっション、10%法、モンテカルロ法です。それぞれのベッティングシステムの詳細については参考文献を参考にしてください。

##ソースコード
プログラミングは得意ではないので、
コードに間違いがあったり、こうしたらいいなどありましたら、ご教示お願いいたします。

```python
import random
import sys
import matplotlib.pyplot as plt
import seaborn
#パラメータの設定
#--------------------------------------------------------------------------------------------------------------------
start_money = 100#初期資金
prob = 50#勝率
odds = 2#オッズ
start_bet = 1#最初のベット額
Num_trial = 500#試行回数
martin_param = 2#マーチンゲール法で負けた場合のベットの増加額
count = 0
#--------------------------------------------------------------------------------------------------------------------

#初期化
#--------------------------------------------------------------------------------------------------------------------
money_key = ["martin_money","revmartin_money","dalembert_money","east_coast_money","tenpercent_money","monte_carlo_money"]
bet_key = ["martin_bet","revmartin_bet","dalembert_bet","east_coast_bet","tenpercent_bet","monte_carlo_bet"]
money_value = []
bet_value = []
for i in range(len(money_key)):
  money_value.append(start_money)
  bet_value.append(start_bet)
dict_money = dict(zip(money_key,money_value))
dict_betting = dict(zip(bet_key,bet_value))
monte_carlo_situ = [1,2,3]

judge_martin = True
judge_revmartin = True
judge_dalembert = True
judge_east_coast = True
judge_tenpercent = True
judge_monte_carlo = True
martin_money_hist = [start_money]
revmartin_money_hist = [start_money]
dalembert_money_hist = [start_money]
east_coast_money_hist = [start_money]
tenpercent_money_hist = [start_money]
monte_carlo_money_hist = [start_money]
x = range(1,Num_trial)
win_count =0
#--------------------------------------------------------------------------------------------------------------------

#勝ったかどうか判定
#--------------------------------------------------------------------------------------------------------------------
def judge_vectory(prob):
    N = random.randint(1, 100)
    if N <= prob:
        judge = True #あたり
    else:
        judge = False #はずれ
    return judge
#--------------------------------------------------------------------------------------------------------------------

#勝った場合、負けた場合のお金の計算
#--------------------------------------------------------------------------------------------------------------------
def money_cal(judge,bet,money,odds):
    if judge:
        money += bet*odds-bet
    else:
        money -= bet
    return money
#--------------------------------------------------------------------------------------------------------------------

#終了判定
#--------------------------------------------------------------------------------------------------------------------
def judge_continue(money,i,method):
    if money <= 0:
        print(method + "は"+str(i)+"回で終了")
        judge_method = False
    else:
        judge_method = True
    return judge_method
#--------------------------------------------------------------------------------------------------------------------

#以下各種のベッティングシステムのコード
#--------------------------------------------------------------------------------------------------------------------
def martingale(judge,money,bet,odds,start_bet,judge_method,i,money_hist):
    if judge_method:
        money = money_cal(judge, bet, money, odds)
        money_hist.append(money)
        judge_method = judge_continue(money, i, "マーチンゲール法")
        if judge:
            bet = start_bet
        else:
            bet *= martin_param
    else:
        money_hist.append(money)
    return money,bet,judge_method

def revmartingale(judge,money,bet,odds,start_bet,judge_method,i,money_hist):
    if judge_method:
        money = money_cal(judge, bet, money, odds)
        money_hist.append(money)
        judge_method = judge_continue(money, i, "逆マーチンゲール法")
        if judge:
            if bet == start_bet * martin_param**3:
                bet = start_bet
            else:
                bet *= martin_param
        else:
            bet = start_bet
    else:
        money_hist.append(money)
    return money,bet,judge_method
def dalembert(judge,money,bet,odds,start_bet,judge_method,i,money_hist):
    if judge_method:
        money = money_cal(judge, bet, money, odds)
        money_hist.append(money)
        judge_method = judge_continue(money, i, "ダランベール法")
        if judge:
            bet += 1
        else:    
            if bet == start_bet:
                pass
            else:
                bet -= 1
    else:
        money_hist.append(money)
    return money,bet,judge_method

def east_coast(judge,money,bet,odds,start_bet,judge_method,i,money_hist):
    if judge_method:
        money = money_cal(judge, bet, money, odds)
        money_hist.append(money)
        judge_method = judge_continue(money, i, "イーストコースト法")
        if judge:
            bet += (bet*odds)/2
        else:
            bet = start_bet
        if money <= 0:
            finish = False
    else:
        money_hist.append(money)
    return money,bet,judge_method

def ten_percent(judge,money,bet,odds,start_bet,judge_method,i,money_hist):
    if judge_method:
        money = money_cal(judge, bet, money, odds)
        money_hist.append(money)
        judge_method = judge_continue(money, i, "テンパーセント法")
        bet = money*0.1
    else:
        money_hist.append(money)
    return money,bet,judge_method

def monte_carlo(judge,money,bet,odds,start_bet,judge_method,i,money_hist,monte_carlo_situ):
    bet  = (monte_carlo_situ[0]+ monte_carlo_situ[-1])*0.5
    print(bet)
    print(monte_carlo_situ)
    print(money)
    if judge_method:
        money = money_cal(judge, bet, money, odds)
        money_hist.append(money)
        judge_method = judge_continue(money, i, "モンテカルロ法")
        if judge:
            if len(monte_carlo_situ) <= 5:
                monte_carlo_situ = [1,2,3]
            else:
                del monte_carlo_situ[0]
                del monte_carlo_situ[0]
                del monte_carlo_situ[-1]
                del monte_carlo_situ[-1]    
        else:
            monte_carlo_situ.append(bet*2)
    else:
        money_hist.append(money)
    return money,bet,judge_method,monte_carlo_situ
#--------------------------------------------------------------------------------------------------------------------


if __name__ == "__main__":
    for i in range(1,Num_trial-1):
        judge = judge_vectory(prob)
        if judge:
            win_count += 1
        dict_money["martin_money"],dict_betting["martin_bet"],judge_martin  = martingale(judge, dict_money["martin_money"], dict_betting["martin_bet"], odds, start_bet,judge_martin,i,martin_money_hist)
        dict_money["revmartin_money"],dict_betting["revmartin_bet"],judge_revmartin  = revmartingale(judge, dict_money["revmartin_money"], dict_betting["revmartin_bet"], odds, start_bet,judge_revmartin,i,revmartin_money_hist)
        dict_money["dalembert_money"],dict_betting["dalembert_bet"],judge_dalembert  = dalembert(judge, dict_money["dalembert_money"], dict_betting["dalembert_bet"], odds, start_bet, judge_dalembert, i, dalembert_money_hist)
        dict_money["east_coast_money"],dict_betting["east_coast_bet"],judge_east_coast  = east_coast(judge, dict_money["east_coast_money"], dict_betting["east_coast_bet"], odds, start_bet, judge_east_coast, i, east_coast_money_hist)
        dict_money["tenpercent_money"],dict_betting["tenpercent_bet"],judge_tenpercent  = ten_percent(judge, dict_money["tenpercent_money"], dict_betting["tenpercent_bet"], odds, start_bet, judge_tenpercent, i, tenpercent_money_hist)
        dict_money["monte_carlo_money"],dict_betting["monte_carlo_bet"],judge_monte_carlo,monte_carlo_situ = monte_carlo(judge, dict_money["monte_carlo_money"], dict_betting["monte_carlo_bet"], odds, start_bet, judge_monte_carlo, i, monte_carlo_money_hist,monte_carlo_situ)

    if judge_martin:
        print("マーチンゲール法は"+str(dict_money["martin_money"])+"円で終了")
    if judge_revmartin:
        print("逆マーチンゲール法は"+str(dict_money["revmartin_money"])+"円で終了")
    if judge_dalembert:
        print("ダランベール法は"+str(dict_money["dalembert_money"])+"円で終了")
    if judge_east_coast:
        print("イーストコースト法は"+str(dict_money["east_coast_money"])+"円で終了")
    if judge_tenpercent:
        print("テンパーセント法は"+str(dict_money["tenpercent_money"])+"円で終了")
    if judge_monte_carlo:
        print("モンテカルロ法は"+str(dict_money["monte_carlo_money"])+"円で終了")

print(win_count/Num_trial)#勝率の計算
#描画
#--------------------------------------------------------------------------------------------------------------------
plt.plot(x,martin_money_hist,label="Martin method")
plt.plot(x,revmartin_money_hist,label="Pare method")
plt.plot(x,dalembert_money_hist,label="Dalembert method")
plt.plot(x,east_coast_money_hist,label="East coast method")
plt.plot(x,tenpercent_money_hist,label="Ten percent method")
plt.plot(x,monte_carlo_money_hist,label="Monte_carlo")
plt.legend()
plt.show()
#--------------------------------------------------------------------------------------------------------------------
    
```

##今回の条件
今回の条件はルーレットを想定して次のようにしてあります。
・初期資金100ドル
・勝率は赤だけにかけ続けたとして50％と仮定
・最初のベットは1ドルから
・試行回数は500回
・オッズは2倍
・パーレー法は3連勝した時点で1ドルに戻している

##結果
![temp.png](https://qiita-image-store.s3.amazonaws.com/0/184254/5968e507-7de4-516b-3467-7534f679a3a4.png)

横軸は試行回数、縦軸は資金です。
今回の試行では利益が出たのはマーチンゲール法とモンテカルロ法の2つでした。条件によって、マーチンゲール法は連敗した場合に資金が0となる場合がありました。また、ベッティングシステムによっては適切なタイミングで終了すれば利益が出るということも分かりました。今後は適切な終了タイミングを求めたいと思います。

##参考文献

https://ja.wikipedia.org/wiki/%E3%83%99%E3%83%83%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0

http://www.silversandscasino.jp/strategy/martingale.php