2021年3月6日 星期六

[Python][量化狼]Monte Carlo Simulation蒙地卡羅模擬下的交易天選之人


自從上次開始討論起策略的參數(勝率與賺賠比)

有許多粉絲私訊說,很多他們自己的策略參數都比這好,可以承受很高風險

好的策略自然可以承受更高風險,但策略的優良與否不在今日討論範圍內



以上述策略來說

策略勝率: 31%

策略賺賠比: 2.7

首先我確認策略是一個正期望值的策略


0.31(勝率)*2.7(賺錢數)+0.69(賠率)*-1(賠錢數)=0.14

這代表說 如果是一個無窮回合的賭局,我可以永遠在市場上賺錢

但這樣就可以保證我可以在市場上賺錢嗎?  錯!

有兩個問題要探討

1.市場不是無窮賭局,人的生命有限

2.一次該下多少賭注


所以今天採用蒙地卡羅模擬(Monte Carlo Simulation),讓我來扮演創造賭局的上帝

1.首先我讓賭局最多可以連續賭250次,因為我認為人的耐心最多只有一年(250日)(甚至更少)

2.我認為一般人風險只拿本金10%, 一次只拿資本的10%下去賭

以本金100萬來說:

假設第一次贏,第二次輸

第一次贏  (100*10%)*2.7+100=127萬  第一次交易結束

第二次輸 (127*10%)*-1+127=114.3萬 第二次交易結束

第三次..... 以此類推交易至250個交易日為止

並時光回溯100次,且把過程記錄下來


在所有參數與策略都不變的情況下,我得到一個有趣的結果

我發現100次中有一次居然特別不一樣,

出現了一位天選之人              100萬交易250天 獲利22億

這位天選之人所用的策略跟風險跟其他99次的人都一樣

唯一的不同只有     隨機變數產生的隨機性  

把100次結果統計了一下得到下圖

       我們看到最終資本那一列
       交易250次後資本剩0~10萬的只有16人
                                       10萬~50萬的有15人
                                       50萬~100萬的有9人
                                       100萬~500萬的有26人
                                       500萬~1000萬的有8人
                                       1000萬以上的有26人
                                             
          有趣的是100次中有40%(16+15+9)是賠錢
          
         甚至有31%(16+15)的人是陣亡的(本金低於50萬)

他們跟天選之人有差嗎? 所用的策略與下注方式都一樣,為何結果天差地遠?

為何你變成了窮人,別人就可以成為天選之人?

一切都是小樣本數裡               隨機性力量的結果

         即便是正期望值的策略

         在小樣本的模擬中,還是會出現賠錢  而且比率還不低 (40%)

         "要對市場感到敬畏"

        因為隨機性可以讓你天選之人變成 破產之人

        最後放上一張 Respect 偶像的照片與Python程式碼


**************Python 程式碼*************

import pandas as pd

import numpy as np

import random

import matplotlib.pyplot as plt

pwin=0.31 #策略勝率

b=2.71#策略賺賠比

def play_game(f, cash=100, m=250):

    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=1, f=0.1, cash=100, m=250):

    res = []

    for i in range(n):

        res.append(play_game(f, cash, m)) 

    return pd.DataFrame(res).sum(axis=0) / n   


n = 1       # 重複次数

cash = 100 # 初始資金100萬

df=pd.DataFrame()

for j in range(1,101):

    res2 = montecarlo(n, fk, cash, m)

    df=pd.concat([df,pd.DataFrame(res2)],axis=1) 

plt.figure(figsize=(20,10))

plt.plot(df)

**************Python 程式碼*************