用Python分析股票的收益和風(fēng)險(xiǎn)

本文將用Python編程涯贞,帶你了解股票投資收益和風(fēng)險(xiǎn)的基本知識(shí)均践。

一椒袍、股票的收益

1.1 導(dǎo)入CSV時(shí)序數(shù)據(jù)

本文將分析微軟2000年以來(lái)的股票交易數(shù)據(jù)(點(diǎn)我下載哦)藕施,它是一個(gè) csv 格式的時(shí)間序列數(shù)據(jù)寇损。你將使用 pandas 讀取 csv 數(shù)據(jù),并存儲(chǔ)為DataFrame格式裳食。

# 導(dǎo)入pandas包
import pandas as pd

# 讀取csv文件矛市,并將‘Date’列解析為日期時(shí)間格式,并設(shè)為索引
StockPrices = pd.read_csv('MSFTPrices.csv', parse_dates=['Date'], index_col='Date')

# 將數(shù)據(jù)按日期這一列排序(保證后續(xù)計(jì)算收益率的正確性)
StockPrices = StockPrices.sort_values(by='Date')

# 打印數(shù)據(jù)的前5行
print(StockPrices.head())
              Open    High     Low     Close    Volume   Adjusted
Date                                                             
2000-01-03  88.777  89.722  84.712  58.28125  53228400  38.527809
2000-01-04  85.893  88.588  84.901  56.31250  54119000  37.226345
2000-01-05  84.050  88.021  82.726  56.90625  64059600  37.618851
2000-01-06  84.853  86.130  81.970  55.00000  54976600  36.358688
2000-01-07  82.159  84.901  81.166  55.71875  62013600  36.833828

該股票數(shù)據(jù)包括了交易日期、開盤價(jià)诲祸、最高價(jià)浊吏、最低價(jià)、收盤價(jià)救氯、調(diào)整后的收盤價(jià)以及成交量找田。其中調(diào)整后的收盤價(jià)最為重要,它對(duì)股票分割着憨、股息和其他公司行為進(jìn)行了標(biāo)準(zhǔn)化墩衙,能真實(shí)地反映股票隨時(shí)間的回報(bào)。所以本文后續(xù)的計(jì)算都是基于調(diào)整后的收盤價(jià)(Adjusted)這一列數(shù)據(jù)。

1.2 計(jì)算收益率

收益率的計(jì)算公式如下:

R_{t2} = \frac{P_{t2} - P_{t1}}{P_{t1}}

這里可理解為兩天的價(jià)格差除以前一天的價(jià)格漆改。在 pandas 中心铃,使用 .pct_change() 方法來(lái)計(jì)算收益率。

# 增加一列'Returns', 存儲(chǔ)每日的收益率
StockPrices['Returns'] = StockPrices['Adjusted'].pct_change()

# 檢查前5行數(shù)據(jù)
print(StockPrices.head())
              Open    High     Low     Close    Volume   Adjusted   Returns
Date                                                                       
2000-01-03  88.777  89.722  84.712  58.28125  53228400  38.527809       NaN
2000-01-04  85.893  88.588  84.901  56.31250  54119000  37.226345 -0.033780
2000-01-05  84.050  88.021  82.726  56.90625  64059600  37.618851  0.010544
2000-01-06  84.853  86.130  81.970  55.00000  54976600  36.358688 -0.033498
2000-01-07  82.159  84.901  81.166  55.71875  62013600  36.833828  0.013068

數(shù)據(jù)框增加了 Returns 一列挫剑,即股票的收益去扣。注意第一天的收益率是缺失值 NaN,因?yàn)闆]有前一天的數(shù)據(jù)用于計(jì)算樊破。
為了后續(xù)計(jì)算方便愉棱,我們選取 Returns 這一列,并將缺失值丟棄哲戚,存儲(chǔ)在新的變量 clean_returns 中奔滑。使用 .dropna() 方法來(lái)刪除缺失值。

clean_returns = StockPrices['Returns'].dropna()

繪制每日收益隨時(shí)間變化的圖惫恼。

# 導(dǎo)入matplotlib繪圖包中的pyplot模塊
import matplotlib.pyplot as plt

#繪圖
clean_returns.plot()
plt.show()

1.3 收益的均值

均值是最常用的統(tǒng)計(jì)量,它將一串?dāng)?shù)據(jù)平均后濃縮為一個(gè)數(shù)值澳盐,但同時(shí)也丟失了數(shù)據(jù)波動(dòng)性的信息祈纯。

可使用 numpy 包中的 mean() 函數(shù)計(jì)算股票歷史收益的均值。

# 導(dǎo)入numpy包
import numpy as np

# 計(jì)算股票的日平均收益
mean_return_daily = np.mean(clean_returns)
print("日平均收益:", mean_return_daily)
日平均收益: 0.00037777546435757725

通過(guò)以下公式叼耙,將日收益率轉(zhuǎn)換為年化收益率(一般假設(shè)一年252個(gè)交易日)腕窥,其中 \mu 是日平均收益率。

平均年化收益率 =(1+\mu)^{252}?1

# 計(jì)算平均年化收益
mean_return_annualized = ((1 + mean_return_daily)**252) - 1
print("平均年化收益:", mean_return_annualized)
平均年化收益: 0.09985839482858783

1.4 收益的分布

繪制收益的直方圖可了解其分布情況筛婉,同時(shí)也能觀察到收益中的異常值簇爆。一般在收益分布的兩側(cè)有兩條長(zhǎng)長(zhǎng)的尾巴,在投資時(shí)一般會(huì)盡量避免左側(cè)尾巴上的異常值爽撒,因?yàn)樗麄兇砹溯^大的虧損入蛆;而分布在右側(cè)尾巴上的異常值通常是件好事,它代表較大的盈利硕勿。

使用 matplotlib 繪圖包中的 hist()函數(shù)繪制直方圖哨毁。

# 繪制直方圖
plt.hist(clean_returns, bins=75)
plt.show()

上圖所示的收益是個(gè)怎樣的分布呢?是正態(tài)分布嗎源武?我們將在后續(xù)揭曉答案扼褪。

二、風(fēng)險(xiǎn)的衡量

金融市場(chǎng)的風(fēng)險(xiǎn)是對(duì)不確定性的度量粱栖,反應(yīng)在收益的波動(dòng)上话浇。一般可用以下統(tǒng)計(jì)量來(lái)表示:

  • 方差或標(biāo)準(zhǔn)差
  • 偏度
  • 峰度

接下來(lái)我們將逐個(gè)計(jì)算它們。

2.1 方差

方差是對(duì)數(shù)據(jù)離散程度的度量闹究。下圖中藍(lán)色分布比紅色分布的方差大得多幔崖,其數(shù)據(jù)也更加分散。

圖片來(lái)源:https://en.wikipedia.org/wiki/Standard_deviation

標(biāo)準(zhǔn)差又稱均方差,是方差的算數(shù)平方根岖瑰。投資回報(bào)中較高的標(biāo)準(zhǔn)差意味著較高的風(fēng)險(xiǎn)叛买,因?yàn)閿?shù)據(jù)分布離均值更遠(yuǎn)了,收益的波動(dòng)幅度更大蹋订。

可使用 numpy 包中的 std() 函數(shù)計(jì)算標(biāo)準(zhǔn)差 \sigma率挣,方差則是標(biāo)準(zhǔn)差的平方 \sigma^2.

# 計(jì)算標(biāo)準(zhǔn)差
sigma_daily = np.std(clean_returns)
print("標(biāo)準(zhǔn)差: ", sigma_daily)

# 計(jì)算方差
variance_daily = sigma_daily ** 2
print("方差: ", variance_daily)
標(biāo)準(zhǔn)差:  0.019341100408708328
方差:  0.0003740781650197374

以上計(jì)算的是每日的方差,我們可以將之轉(zhuǎn)化成年化方差露戒。將標(biāo)準(zhǔn)差乘以交易日數(shù)目的平方根椒功,得到年化標(biāo)準(zhǔn)差。將年化標(biāo)準(zhǔn)差平方智什,就得到年化方差动漾。

# 計(jì)算年化標(biāo)準(zhǔn)差
sigma_annualized = sigma_daily*np.sqrt(252)
print("年化標(biāo)準(zhǔn)差:", sigma_annualized)

# 計(jì)算年化方差
variance_annualized = sigma_annualized ** 2
print("年化方差:", variance_annualized)
年化標(biāo)準(zhǔn)差: 0.3070304505826317
年化方差: 0.09426769758497383

2.2 偏度

偏度是數(shù)據(jù)分布偏斜方向和程度的度量,反應(yīng)分布的非對(duì)稱性荠锭。

下圖所示的曲線分別代表了負(fù)偏態(tài)和正偏態(tài)旱眯。在金融領(lǐng)域,人們更傾向于正的偏度证九,因?yàn)檫@意味著高盈利的概率更大删豺。

圖片來(lái)源:https://en.wikipedia.org/wiki/Skewness

可使用 scipy.stats 提供的 skew() 函數(shù)計(jì)算收益分布的偏度。

# 從 scipy.stats 導(dǎo)入skew函數(shù)
from scipy.stats import skew

# 計(jì)算收益分布的偏度
returns_skewness = skew(clean_returns)
print("偏度:", returns_skewness)
偏度: 0.21935459193067852

回顧之前繪制的收益分布圖愧怜,乍看之下似乎是對(duì)稱分布呀页,但經(jīng)過(guò)偏度的計(jì)算,我們知道它具有稍許的正偏度拥坛。

2.3 峰度

峰度表征概率密度分布曲線在平均值處峰值高低的特征數(shù)蓬蝶,反映了峰部的尖度。通常將樣本的峰度和正態(tài)分布相比較猜惋,因?yàn)檎龖B(tài)分布的峰度是3丸氛,所以將超出3的部分稱為超值峰度。大部分金融收益都具有正的超值峰度著摔。

kurtosis.png

使用scipy.stats提供的 kurtosis() 函數(shù)計(jì)算分布的超值峰度雪位。

# 從 scipy.stats 導(dǎo)入 kurtosis 函數(shù)
from scipy.stats import kurtosis

# 計(jì)算收益分布的超值峰度
excess_kurtosis = kurtosis(clean_returns)
print("超值峰度:", excess_kurtosis)

# 計(jì)算峰度
fourth_moment = excess_kurtosis + 3
print("峰度:", fourth_moment)
超值峰度: 10.31457261802553
峰度: 13.31457261802553

上述峰度的計(jì)算結(jié)果表明,該股票收益的峰比正態(tài)分布高得多梨撞。我們也可通過(guò)下圖概率密度分布的比較看出來(lái)雹洗,圖中橙色代表收益的分布,而藍(lán)色表正態(tài)分布卧波。

# 模擬正態(tài)分布數(shù)據(jù)时肿,其均值和標(biāo)準(zhǔn)差與文中的股票收益相同。
mu = mean_return_daily
sigma = sigma_daily
norm = np.random.normal(mu, sigma, size=10000)
# 繪制正態(tài)分布的概率密度分布圖
plt. hist(norm, bins=100, alpha=0.8, density=True, label='Normal Distribution')

# 繪制收益的概率密度分布圖
plt.hist(clean_returns, bins=75, alpha=0.7, density=True, label='Returns')

# 增加圖例說(shuō)明
plt.legend()
# 繪圖
plt.show()

三港粱、收益分布正態(tài)性檢驗(yàn)

現(xiàn)在讓我們回到第一部分結(jié)尾提出的問(wèn)題:該股票的收益分布是正態(tài)分布嗎螃成?

我們知道正態(tài)分布是對(duì)稱的旦签,其偏度為0,而該股票收益具有正的偏度0.219寸宏。正態(tài)分布的峰度是3宁炫,而該股票收益的峰度高達(dá)13.31。從這兩個(gè)統(tǒng)計(jì)量看出氮凝,該股票收益并不是正態(tài)分布羔巢,它稍微向右偏斜,并且具有比較尖的峰罩阵。

但是這就能讓我們自信的下結(jié)論嗎竿秆?為了判斷股票收益分布的正態(tài)性,我們需要使用真正的統(tǒng)計(jì)檢驗(yàn)方法稿壁,而不是簡(jiǎn)單地檢查峰度或偏度幽钢。

這里使用 scipy.stats 提供的 shapiro() 函數(shù),對(duì)股票收益分布進(jìn)行 Shapiro-Wilk 檢驗(yàn)傅是。該函數(shù)有兩個(gè)返回值匪燕,一個(gè)是檢驗(yàn)的t統(tǒng)計(jì)量,另一個(gè)是p值⌒剩現(xiàn)在你并不需要知道 Shapiro-Wilk 檢驗(yàn)到底是個(gè)什么鬼帽驯,只要知道如何使用p值判斷數(shù)據(jù)的正態(tài)性:如果p值小于等于0.05,就拒絕正態(tài)性假設(shè)溃斋,得出數(shù)據(jù)非正態(tài)分布的結(jié)論界拦。

# 從 scipy.stats 導(dǎo)入shapiro
from scipy.stats import shapiro

# 對(duì)股票收益進(jìn)行Shapiro-Wilk檢驗(yàn)
shapiro_results = shapiro(clean_returns)
print("Shapiro-Wilk檢驗(yàn)結(jié)果: ", shapiro_results)

# 提取P值
p_value = shapiro_results[1]
print("P值: ", p_value)
Shapiro-Wilk檢驗(yàn)結(jié)果:  (0.9003633260726929, 0.0)
P值:  0.0

計(jì)算得到的p值非常小吸申,在目前的精度下等于0梗劫,所以我們可以肯定地說(shuō)該收益分布不是正態(tài)分布。

小結(jié)

本文用Python計(jì)算了股票的收益和風(fēng)險(xiǎn)截碴,我們首先查看了股票的收益率及其分布梳侨,接著計(jì)算指示風(fēng)險(xiǎn)的統(tǒng)計(jì)量:方差、偏度和峰度日丹,最后檢驗(yàn)了收益分布的正態(tài)性走哺。

另外我們還學(xué)到了以下統(tǒng)計(jì)函數(shù):

import numpy as np
np.mean()   # 均值
np.std()    # 標(biāo)準(zhǔn)差

from scipy.stats import skew, kurtosis, shapiro
skew()      # 偏度
kurtosis()  # 超值峰度
shapiro()   # Shapiro-Wilk檢驗(yàn)正態(tài)性

如果你想自己下載股票數(shù)據(jù)的話,可以參考這篇文章 《如何用Python下載金融數(shù)據(jù)》哲虾。


注:本文是 DataCamp 課程 Intro to Portfolio Risk Management in Python 的學(xué)習(xí)筆記丙躏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市束凑,隨后出現(xiàn)的幾起案子晒旅,更是在濱河造成了極大的恐慌,老刑警劉巖汪诉,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件废恋,死亡現(xiàn)場(chǎng)離奇詭異谈秫,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)鱼鼓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門拟烫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人迄本,你說(shuō)我怎么就攤上這事硕淑。” “怎么了岸梨?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵喜颁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我曹阔,道長(zhǎng)半开,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任赃份,我火速辦了婚禮寂拆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抓韩。我一直安慰自己纠永,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布谒拴。 她就那樣靜靜地躺著尝江,像睡著了一般。 火紅的嫁衣襯著肌膚如雪英上。 梳的紋絲不亂的頭發(fā)上炭序,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音苍日,去河邊找鬼惭聂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛相恃,可吹牛的內(nèi)容都是我干的辜纲。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼拦耐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耕腾!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起杀糯,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扫俺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后火脉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牵舵,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柒啤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了畸颅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片担巩。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖没炒,靈堂內(nèi)的尸體忽然破棺而出涛癌,到底是詐尸還是另有隱情,我是刑警寧澤送火,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布拳话,位于F島的核電站,受9級(jí)特大地震影響种吸,放射性物質(zhì)發(fā)生泄漏弃衍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一坚俗、第九天 我趴在偏房一處隱蔽的房頂上張望镜盯。 院中可真熱鬧,春花似錦猖败、人聲如沸速缆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)艺糜。三九已至,卻和暖如春幢尚,著一層夾襖步出監(jiān)牢的瞬間破停,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工侠草, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辱挥,地道東北人犁嗅。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓边涕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親褂微。 傳聞我的和親對(duì)象是個(gè)殘疾皇子功蜓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容