所謂蒙特卡洛模擬,就是隨機(jī)產(chǎn)生大量的資產(chǎn)分配方案候醒,然后再計(jì)算各種分配方案下能颁,所得到的波動率、夏普率倒淫,再根據(jù)最優(yōu)的夏普率伙菊,反查資產(chǎn)分配方案。
主要操作我們在上一節(jié)已經(jīng)介紹過敌土,這一步主要做的事情是不斷地重復(fù)镜硕。我們先把代碼給出來,再進(jìn)行解釋:
num_ports = 5000
w = np.zeros((num_ports, len(stocks)))
vol_arr = np.zeros(num_ports)
sharpe_arr = np.zeros(num_ports)
port_return_arr = np.zeros((num_ports, len(returns)))
cov_arr = np.zeros(num_ports)
for i in range(num_ports):
weights = np.array(np.random.random(len(stocks)))
weights = weights/np.sum(weights)
w[i,:] = weights
weighted_returns = weights * returns
port_return_i = weighted_returns.sum(axis=1)
port_return_arr[i,:] = port_return_i
cov = np.cov(port_return_i)
cov_arr[i] = cov
vol_arr[i] = np.sqrt(np.dot(weights.T, np.dot(cov, weights)))
sharpe_arr[i] = sharpe_ratio(port_return_i)
我們主要定義了這樣四個(gè)數(shù)組:
- 權(quán)重矩陣 all_weights返干。我們打算重復(fù) 5000 次采樣兴枯,由于資產(chǎn)組合共有 4 個(gè)標(biāo)的,所以矩欠,它是一個(gè) 5000 * 4 的矩陣财剖。每一行對應(yīng)一次資產(chǎn)組合分配。
- 夏普率數(shù)組癌淮。它是一個(gè) size 為 5000 的數(shù)組躺坟,記錄了每一次計(jì)算出來的 sharepe 率。
- 波動率數(shù)組乳蓄。它也是一個(gè) size 為 5000 的數(shù)組瞳氓,記錄了每一次計(jì)算郵來的波動率。
- port_return_arr,在示例中匣摘,它是一個(gè) 5000 * 241 大小的矩陣店诗,每一行記錄了組合在過去一年中每一天的收益。
當(dāng)上述代碼運(yùn)行完成之后音榜,我們就得到了 5000 組夏普值庞瘸。根據(jù)夏普值的定義,我們直接找到夏普值最大的那一組赠叼,就是風(fēng)險(xiǎn)最小擦囊、收益最高的資產(chǎn)組合。
最佳投資組合
我們使用 np.argmax 來尋找夏普最大時(shí)的位置嘴办,此點(diǎn)即為最佳投資組合:
# 檢查最高的 SHARPE
pos = np.argmax(sharpe_arr)
print(pos, sharpe_arr[pos])
print("stocks", stocks)
print("Portfolio Allocation:", all_weights[pos])
這樣我們得到資產(chǎn)分配方案類似如下:
標(biāo)的 1 | 標(biāo)的 2 | 標(biāo)的 3 | 標(biāo)的 4 | |
---|---|---|---|---|
比例 | 35.3% | 0.3% | 0.8% | 64% |
我們將上述試驗(yàn)結(jié)果繪制成圖形瞬场,來看看是否符合有效前沿理論:
import matplotlib.pyplot as plt
annual_return = np.prod((1 + port_return_arr), axis=1) - 1
plt.scatter(vol_arr, annual_return, c=sharpe_arr, cmap='RdYlBu')
plt.colorbar(label='Sharpe Ratio')
plt.scatter(vol_arr[pos], annual_return[pos], c='red',s=80)
我們以波動率為 x 軸,年化回報(bào)為 y 軸涧郊。在每一個(gè) x 上贯被,都存在若干組年化回報(bào)數(shù)據(jù),有正有負(fù)妆艘。顯然彤灶,對于同一個(gè) x,正好是那些處在有效前沿上的組合批旺,正好是收益最大或者虧損最大的組合幌陕。
按照 MPT 理論,只有那些在 y 軸上方汽煮,且處于有效前沿上的才是值得關(guān)注的組合搏熄,然后根據(jù)我們的風(fēng)險(xiǎn)承受能力,來選擇這條線上對應(yīng)的組合暇赤。
我們把夏普率最高的那組方案心例,用紅色的點(diǎn)標(biāo)注出來◆嶙浚可以看出契邀,它略微偏離了有效前沿,為什么失暴?
[圖片上傳失敗...(image-87f80c-1702050684040)]
這里的原因是坯门,我們使用了年化收益作為 y 軸,但這個(gè)小紅點(diǎn)是用的 sharpe 最大的點(diǎn)逗扒。同一個(gè) sharpe 率古戴,對應(yīng)的收益率不只一個(gè),而是一個(gè)分布矩肩;即使在波動率和 sharpe 率都確定的情況下现恼,年化收益率也仍然不只一個(gè),仍然是一個(gè)分布。關(guān)于夏普率與收益率的關(guān)系叉袍,特別是與最大回撤的關(guān)系始锚,我們在第 21 課講過。這是一個(gè)很重要的問題喳逛。
如果我們把 y 軸換成 sharpe 值瞧捌,則會得到更接近的效前沿理論的一張圖:
[圖片上傳失敗...(image-86d599-1702050684040)]
從走勢圖來看,我們這樣求出來的資產(chǎn)組合確實(shí)是最優(yōu)的润文。但是姐呐,如果我們將它與文章開頭的那個(gè)圖相比,我們會得出什么結(jié)論典蝌?
這把牌不行曙砂。如果你愿意承擔(dān)較大風(fēng)險(xiǎn),這把牌也不能給你想要的收益骏掀。浪得不夠狠鸠澈。
資產(chǎn)組合并沒有形成直觀的有效前沿,原因主要是投資組合整體的收益率受組合內(nèi)資產(chǎn)的收益率限制砖织,即min(組合內(nèi)資產(chǎn)收益率)≤資產(chǎn)組合收益率≤max(組合內(nèi)資產(chǎn)收益率)款侵,因此并不是能實(shí)現(xiàn)所有收益率末荐。
因此我們得到結(jié)論:你得重新選標(biāo)的侧纯。
另外,如果你現(xiàn)在就急于用MPT來進(jìn)行投資甲脏。眶熬。。你還得再學(xué)點(diǎn)啥块请。
歷史當(dāng)然總是在重復(fù)自己娜氏,一切歷史都是當(dāng)代史。但是仍然有很多東西要討論墩新。
首先贸弥,我們應(yīng)該放多少支標(biāo)的到這個(gè)組合里來?我們的示例中只使用了4支海渊,如果我們對滬深300或者中證1000來做指增绵疲,會不會更好一點(diǎn)?
其次臣疑,上述兩幅圖是針對同一資產(chǎn)組合盔憨,不同時(shí)間段情況所形成,很明顯收益及風(fēng)險(xiǎn)都有較大差異讯沈。如果我們在不同的時(shí)間點(diǎn)來優(yōu)化投資組合郁岩,我們得到的倉位顯然會有所不同。因此我們提出問題:我們應(yīng)該多久計(jì)算一次并執(zhí)行調(diào)倉?會不會有這樣一種情況问慎,每次調(diào)倉是在用過去的最優(yōu)解萍摊,而它很快就變成了次優(yōu)或者最劣解?也就是如叼,這個(gè)組合它的動量周期是多久记餐?
顯然,任何一個(gè)有價(jià)值的方案薇正,往往都不是一篇短文能cover的片酝,我們會在后續(xù)的文章中不斷深入探討這個(gè)問題。
好挖腰,我們先放下這些問題雕沿,先來看一個(gè)技術(shù)問題:
執(zhí)行上述循環(huán)5000次,我們花了大約 5.2 秒猴仑。
這是只有4支標(biāo)的的情況审轮。很顯然,隨著標(biāo)的數(shù)的增加辽俗,我們需要暴力搜索的空間也隨之變大疾渣。這種方法,在標(biāo)的數(shù)增加到50支崖飘、100支時(shí)榴捡,是否還可行呢?
下一篇朱浴,我們就來探討這個(gè)問題吊圾。