シーゲルのパラドックス?そんなものは知らんが、期待値はプラスになる。
2020年07月18日、仮想通貨を根城とする悪botter達の間で議論が沸き起こり、それが面白かったのでまとめます(中身があってるかどうかは知らんけど私は納得している)。
bitFlyer Co-Founderである加納裕三さんのツイートからすべてが始まりました。
この問題について、加納さんは次のように結果を発表しました。
この時点では、比較的問題は少なかったと思います。
「は?前提条件としてドリフト0の幾何ブラウン運動ってどこに書いてあるっけ?」みたいな人はあまりいませんでした。
この話題についてある方が「2倍になる確率と0.5倍になる確率が同じなら期待値+になるんですか?」(意訳)と疑問を投げかけたところ以下のような返答がありました。
この時点で、「そっか、積分しないといけないからこうやっては計算できないのか」っと納得する人がいたのかいなかったのかは知りませんが私の感覚としては期待値+になるだろうなと思ったので確かめてみました。
先に結論
2倍になるか0.5倍になるまでにかかる時間を無視していいなら期待値はプラス。
今回の話題では前提条件がかなりあいまいだったのでいろんな人がいろんな前提を置いて話しているのが混乱させる原因になったのだと思います。
私の結論としては期待値が1を超えるのですが、それは「2倍または0.5倍にタッチするまで続ける」という前提があります。
私たちは知らない間に隠れた前提条件を頭に置きがちですね。
この前提条件を一々明らかにしないと会話ができない人とは「なんか話しててしんどいな、面白くないな」っと思う一方、前提条件を明らかにせずとも話が続けられる人のことは好ましく感じます。
日常生活では前提条件を明らかする必要が無い方が圧倒的に楽ですが、ビジネスや研究の場だとこの前提条件は細かく明らかにしたほうがいいです。
会議とかで前提条件が共有されてないと本当地獄、時間の無駄なので。笑
はい、脱線が長くなりましたが説明していきます。
まずは論理的に考えてみた
加納さんが仮定している「ランダムウォーク仮定」を「幾何ブラウン運動」によって支配されていると読み替えましょう。
「上下どっちかにランダムに動く」
すると、収益率は対数正規分布に従うことが知られています。
つまりどういうこと?
ある時点tでの価格をp(t)、t+1時点での価格をp(t+1)とします。
p(t+1)/p(t)が対数正規分布に従うということだと思ってます。笑
はいここで、論理的に考えましょう。
「無限に長く時間を取ったらどっかの時点で2倍になるか、0.5倍になるっしょ常考」→確率が50%ずつになって期待値プラス証明完了ヒャッハーですね。
隠れた前提として「2倍か0.5倍になるまでの期間は考慮しない」というものがあります。
次にシミュレーションしてみた。
仮定として、期待利回り年率0%、年間ボラティリティ50%、初期状態の価格100と置いてます。
# 初期設定
# t0における価格
t0 = 100
# 対数正規分布の平均
mu = 0 * (1/365)
# 対数正規分布の分散
sigma = 0.5 * np.sqrt(1/365)
# 対数正規分布から1000日間の動きをシミュレーションする
diff = np.random.lognormal(mu,sigma,1000)
r_walk = np.cumprod(diff)*t0
# シミュレーション本数
N = 10000
# 過程日数1000日
time = 100
result = np.zeros((N,time))
for i in range(N):
t0 = 100
diff = np.random.lognormal(mu,sigma,time)
r_walk = np.cumprod(diff)*t0
result[i,:] = r_walk
# 開始時点から2倍以上になった場合、そこで打ち切り
# 開始時点から0.5倍以下になった場合、そこで打ち切り
idx = np.where((result>=2*t0) | (result<=0.5*t0))
idx = list(zip(*idx))
df = pd.DataFrame(idx,columns=["N","time"])
# 各サンプルで最初の時刻のみを残す
df = df.drop_duplicates(subset="N")
2倍になったら勝利で終了、0.5倍になったら敗北で終了としましょう
result_2 = np.zeros((N,time))
win = {}
lose = {}
for i in df.values:
if result[i[0],i[1]] >= 2 * t0:
win[i[0]] = i[1]
elif result[i[0],i[1]] <= 0.5 * t0:
lose[i[0]] = i[1]
# 勝利するまでにかかった時間
win_time = []
for key, value in win.items():
win_time.append(value)
# 勝利するまでにかかった時間
lose_time = []
for key, value in lose.items():
lose_time.append(value)
print(f"価格が2倍になったシミュレーション本数は:{N}本中、{len(win)}本。確率: {len(win)/N}")
print(f"価格が0.5倍になったシミュレーション本数は:{N}本中、{len(lose)}本。確率: {len(lose)/N}")
print("=======")
print(f"価格が2倍になるまでにかかった期間の平均は:{np.mean(win_time)}")
print(f"価格が0.5倍になるまでにかかった期間の平均は:{np.mean(lose_time)}")
はい。これをいろんな時間軸で試しました。
N=100000、time=365のとき
N=100000、time=1000のとき
N=10000、time=10000のとき
はい、「2倍になったら勝利で終了、0.5倍になったら敗北で終了、それまで終了しない」という条件でシミュレーションした結果
期待値+ですね。
何か知らんけどシーゲルのパラドックスっていう問題があるらしい。
隠れた前提とか論理的な考え方を身に付けるためのいい本。
前提条件大事
この記事が気に入ったらサポートをしてみませんか?