Python&Colab:「破産の確率」を算出とグラフ化(コピペするだけ!)

Python&Colab:「破産の確率」を算出とグラフ化(コピペするだけ!)

Google Colab および Python で「『破産の確率』を算出する方法」「破産確率表の作成」「破産確率表のグラフ化」「破産の確率の計算式とコードの解説」などを備忘録としてメモ。

破産の確率は、勝率、リスクリワード比率、リスクの許容などの項目から算出する。

コードを公開しているので、Google Colab にコピペして実行すれば1分で計算することができます。

2019年1月30日 修正
1."定額" の「破産の確率」を算出する」「2."定率" の「破産の確率」を算出する」のコードを修正。
2019年1月30日 追記
3.破産確率表を算出して3Dのグラフを描画する」「4.「破産の確率」の計算式とコードの解説」を追記。

この記事のコードで計算すると、以下リンク先の「『破産の確率』計算機」と同じ算出結果になる。

Google Colab:Pythonで「破産の確率」を算出とグラフ化(コピペするだけ!)

  1. "定額" の「破産の確率」を算出する
  2. "定率" の「破産の確率」を算出する
  3. 破産確率表を算出して3Dのグラフを描画する
    1. 必要なモジュールのインストールと読み込み
    2. 破産確率表の算出
    3. 破産確率表をもとに3Dのグラフを描画する
  4. 「破産の確率」の計算式とコードの解説

1."定額" の「破産の確率」を算出する

定額 ≒ 単利

Google Colab: Cell-1

import numpy as np

win_pct     = 0.38     # 勝率
risk_reward = 2.09     # リスクリワード比率
risk_rate   = 0.05     # 1回のトレードで取るリスク率

class ruin_fixed_amonunt():
 
    def __init__( self ,win_pct ,risk_reward ,risk_rate ):
        self.win_pct     = win_pct
        self.risk_reward = risk_reward
        self.risk_rate   = risk_rate
        if self.is_error() : raise
 
    def is_error( self ) :
        if self.win_pct     == 0 \
        or self.risk_reward == 0 \
        or self.risk_rate   == 0 :
            return True
        elif not 0 <= self.win_pct <= 1   \
        or   not 0 <  self.risk_reward    \
        or   not 0 <= self.risk_rate <= 1 :
            return True
        else : 
            return False

    def equation( self ,x ,P ,R ) :
        return P * x**( R + 1 ) + ( 1 - P ) - x

    def solve_equation( self ) :
        S ,P ,R = 0 ,self.win_pct ,self.risk_reward
        while self.equation( S ,P ,R ) > 0:
            S += 1e-4
        if S >= 1 : S = 1
        return S

    def calc( self ) :
        S = self.solve_equation()
        return S ** ( 1 / self.risk_rate )    
    


if __name__=='__main__' :
    ruin_rate = ruin_fixed_amonunt( win_pct ,risk_reward ,risk_rate ).calc()
    print( f"破産確率(定額)は{ ruin_rate :.2%}です" )

算出結果

破産確率(定額)は3.87%です

目次へ

2."定率" の「破産の確率」を算出する

定率 ≒ 複利。定率の場合は項目が増える。

Google Colab: Cell-2

import numpy as np

win_pct     = 0.38     # 勝率
risk_reward = 2.09     # 損益レシオ
risk_rate   = 0.05     # 1回のトレードで取るリスク率
funds       = 1000000  # 初期資金
ruin_line   = 200000   # 撤退ライン(破産)

class ruin_fixed_rate():
 
    def __init__( self ,win_pct ,risk_reward ,risk_rate ,funds ,ruin_line ):
        self.win_pct     = win_pct
        self.risk_reward = risk_reward
        self.risk_rate   = risk_rate
        self.funds       = funds
        self.ruin_line   = ruin_line
        if self.is_error() : raise
 
    def is_error( self ) :
        if self.win_pct     == 0 \
        or self.risk_reward == 0 \
        or self.risk_rate   == 0 \
        or self.ruin_line   == 0 :
            return True
        elif not 0 <= self.win_pct <= 1   \
        or   not 0 <  self.risk_reward    \
        or   not 0 <= self.risk_rate <= 1 \
        or self.funds < 0                 \
        or self.ruin_line < 0             \
        or self.ruin_line > self.funds :
            return True
        else : 
            return False

    def equation( self ,x ,P ,R ) :
        return P * x**( R + 1 ) + ( 1 - P ) - x

    def solve_equation( self ,win_pct ,R ) :
        S ,P = 0 ,win_pct
        while self.equation( S ,P ,R ) > 0:
            S += 1e-4
        if S >= 1 : S = 1
        return S

    def calc( self ) :
        a = np.log( 1 + self.risk_reward * self.risk_rate )
        b = abs( np.log( 1 - self.risk_rate ) )
        n = np.log( self.funds / self.ruin_line )
        R = a / b
        S = self.solve_equation( self.win_pct ,R )
        return S ** ( n / b )



if __name__=='__main__' :
    ruin_rate = ruin_fixed_rate( win_pct ,risk_reward ,risk_rate ,funds ,ruin_line ).calc()
    print( f"破産確率(定率)は{ ruin_rate :.2%}です" )

算出結果

破産確率(定率)は2.46%です

目次へ

3.破産確率表を算出して3Dのグラフを描画する

3-1.必要なモジュールのインストールと読み込み

Google Colab: Cell-3

# Plotly のインストール
!pip install plotly --upgrade

Google Colab: Cell-4

import pandas as pd
import plotly
import plotly.graph_objs as go
import plotly.figure_factory as ff
plotly.offline.init_notebook_mode( connected=True )

# google colabでplotlyを表示するにはこれが必要。
# グラフを書き出すセルごとに使用する
def enable_plotly_in_cell():
    import IPython
    from plotly.offline import init_notebook_mode
    display(IPython.core.display.HTML('''
            
    '''))
    init_notebook_mode( connected=False )

目次へ

3-2.破産確率表の算出

Google Colab: Cell-5

win_range = np.arange(0.3 ,0.62 ,0.02)
rr_range  = np.arange(0.4 ,3.1 ,0.1)
risk_rate = 0.02
funds     = 1000000
ruin_line = 200000

df_ruin = pd.DataFrame()
for win in win_range :
    for rr in rr_range :
        ruin_rate = ruin_fixed_rate( win ,rr ,risk_rate ,funds ,ruin_line ).calc()
        df_ruin.loc[rr ,f'{ win :.0%}'] = f'{ ruin_rate :.2%}'

df_ruin
破産確率表の算出結果

目次へ

3-3.破産確率表をもとに3Dのグラフを描画する

Google Colab: Cell-6

layout = go.Layout( title         = '定率、損失の許容:0.02、元金100万円、破産の基準:20万円'
                  , autosize      = False
                  , paper_bgcolor = "#000"
                  , width         = 1000
                  , height        = 800
                  , scene = dict(
                          aspectmode  = "manual"
                        , aspectratio = dict(x=1 ,y=1 ,z=0.5)
                        , xaxis = dict(color="#fff" ,linecolor="#fff" ,gridcolor="#eee" ,title="リスクリワード比率")
                        , yaxis = dict(color="#fff" ,linecolor="#fff" ,gridcolor="#eee" ,title="勝率")
                        , zaxis = dict(color="#fff" ,linecolor="#fff" ,gridcolor="#eee" ,title="破産の確率")
                        , camera = dict(eye=dict(x=2 ,y=1.25 ,z=1.5)) )
                  , font = dict(color="#fff") )

z1 = df_ruin

data = [ go.Surface( z = z1.as_matrix()
                   , y = z1.index
                   , x = z1.columns
                   , cmin=0 ,cmax=1
                   , colorscale = "Jet"
                   , colorbar   = dict(lenmode='fraction', len=0.5)
                   , contours   = dict(x=dict(color="#fff") ,y=dict(color="#fff") ,z=dict(color="#fff")) ) ]

enable_plotly_in_cell()
plotly.offline.iplot( go.Figure( data=data ,layout=layout ) )
破産確率表の3Dグラフ ruin rate table surface graph

目次へ

4.「破産の確率」の計算式とコードの解説

ここからは、参考にしたサイトから引用しながら、「破産の確率」の計算式とコードについて解説していきたいと思います。計算式については、元のサイトより分かりやすく説明できる自信がないため、コードの解説が主になるかもしれません。ややこしい話なので興味がない方はスルーしちゃってください。

「破産の確率」をシンプルに考える

まずは、引用を。一部、省略したりしています。

<問題>
勝つと a 円もらえ、負けると b 円失う賭がある。勝つ確率を P とする。あなたは、現在、n 円持っている。この賭を際限なく繰り返すとき、破産する(所持金が0以下になる)確率はいくらか。

※ 最後に借金が残る場合もありえます。たとえば、a=15、b=10、n=10 のとき、「勝ち(25円)→ 負け(15円)→ 負け(5円)→ 負け(-5円)」となれば、5円の借金をかかえて破産です。

引用元¥∞:破産の確率

これ以降、引用の中にでてくる「a、b、P、n」などはすべて同じものを指しています。(利益=a など)

P ≦ (a+b) のときは、「1回あたりの期待値≦0」 なので、やるだけ無駄です。この場合、破産の確率は 「1」で、際限なくやっていれば必ず破産します。そこで、以下では P > b / (a+b) とします。

a=b で、n/b が整数の場合、破産の確率は次のようになる。

破産の確率 計算式1

実際に数字を入れて計算してみると以下のようになる。

例)Aさんは、資金 200万円で株をやっている。トレード1回ごとの勝率は 60%で、勝つときは 10万円儲け、負けるときは 10万円損をする。Aさんの破産の確率はいくらか。

破産の確率 計算式2

前述の「a、b、P、n」に当てはめ、「a=b=10、n=200、P=0.6」として計算したもの。これだと「a=b で、n/b が整数の場合」という条件があり不十分。

目次へ

定額の「破産の確率」を計算する

ここで引用元のサイトの方も行き詰まったようです。

というわけで、a=b の場合は簡単です。そうでないときは、どうするのか?

a と b が異なる整数の場合、数式は書き出せるのですが、高次方程式の解(それも複素数の解)を求める必要があり、実用的でありません。簡単な近似式がないものかと少し考えてみたのですが、わかりませんでした。

そこで近所の図書館へ行き、『確率論とその応用』という本(W・フェラー著、確率論の名著らしいです)を借りてパラパラ見てみると …。ありました!!さすがに名著といわれるだけのことはあります(笑)

引用元¥∞:破産の確率

ここでついに、欲しかった計算式がでてきます。

フェラーの本に出ている式に少し手を加えることで、次のように結論できます。

まず損益比 R を R=a/b で定義します。
0<x<1 の範囲における、次の方程式の解を S とします(この範囲における解は1つしかありません)。

破産の確率 計算式3

このとき、次の評価式が成立します。

破産の確率 計算式4

n/b と R がともに整数の場合は、右辺の等号が成立します。つまり、破産の確率=S^(n/b) です。

※ この評価式の証明は、数学の素養があればそれほど難しくありません。知りたい人は、フェラーの本を見てください。フェラーの 『確率論とその応用』 は、「1」 と 「2」 があり、それぞれ上巻・下巻に分かれています(つまり全4巻)。この評価式は、「1」 の下巻、461ページにある式(8・12)から導くことができます。

ここまでを関数化したのが、定額の「破産の確率」を求めるruin_fixed_amonunt()です。

1."定額" の「破産の確率」を算出する」と見比べながらお読みいただきたいのですが、def equation( self ,x ,P ,R )P * x**( R + 1 ) + ( 1 - P ) - xが上記の方程式を表しています。これをsolve_equation()で解いているわけです。具体的には、数字を代入しまくって近い数字を探しています。

そして、方程式から求めた「S」を元にS ** ( 1 / self.risk_rate )で「破産の確率」を求めています。

目次へ

定率の「破産の確率」の計算

さて、賭け金を一定にするのではなく、資金に対して一定の比率で賭けていく場合はどうでしょうか。

つまり、その時点の資金を A 円とするとき、一定の比率 k (0<k<1)を用いて、勝てば R×k×A 円儲け、負ければ k×A 円損するように賭けるとします。

※ たとえば、損益比 R(=利益÷損失)が 2 とします。k=0.1 なら、常に資金の 10%をリスクにさらします。資金 100万円なら、負けは 10万円の損、勝ちは 20万円の得となるように賭け、それに勝って資金が 120万円になれば、次は、負けは 12万円の損、勝ちは 24万円の得となるように賭けるわけです。

はじめの資金を A₀円とし、資金が B 円以下になったら破産とします。
W 回勝って、L 回負けたとき、資金が B 円以下になって破産する条件は、次の式です。

破産の確率 計算式5

対数をとって変形すると次のようになります。

破産の確率 計算式6

a、b、n を次のように定義します。

破産の確率 計算式7

そうすると上の式は

破産の確率 計算式8

と同じことです。

結局、この問題は 「資金が n 円、勝つと a 円儲け、負けると b 円失うときの破産の確率は?」 と同じです。つまり、このページのはじめの <問題> に還元されるわけです。上に書いた確率の評価式は、a、b、n が整数でなくても成立するので、それを適用すれば評価が出せます。

引用元¥∞:破産の確率

と、ここで引用元の記事は終わっています。

これは、「定率にしたことで『a、b、n』の考え方は変わったけど、全体の考え方は一緒だよね」ということです。つまり、あらたな『a、b、n』を定額の計算式に代入してあげれば「定率の『破産の確率』」を算出することができます。

この説明を踏まえて「2."定率" の「破産の確率」を算出する」をみてみると、ruin_fixed_rate()の全体の構成がruin_fixed_amount()とほぼ同一であることが分かると思います。"定率" の計算式は、"定額" のそれに項目を追加し、定率用の「a、b、n」を別途算出すれば、あとは同様の計算で良いわけです。

目次へ

Back to Top

最高のトレード環境を実現する「サクソバンク証券」

ボクが唯一つかっている取引会社です。

世界中のほとんどの市場に対応していて、日本株をCFDで取引すれば個別株とFXの損益を通算することもできます。何よりも、ひとつの口座に入金するだけですべての銘柄を取引できるのが本当に便利。

SaxoTraderGO
  • 「FX口座」150以上の通貨ペア
  • 「株価指数CFD口座」約250種類
  • 「個別株CFD口座」日米中など世界22カ国・34市場
  • 「バラエティCFD口座」債券やVIX、商品など約100種類
  • MT4にも対応!

Investment Tech Hack

Sorry... doesn't support your browser

To get the best possible experience using our site we recommend that you upgrade to a modern web browser. Investment Tech Hackではご利用中のブラウザサポートはしていません。
Internet Explorerのアップグレード行う、もしくはその他のブラウザを使用しての閲覧をお願いします。