Python3對股票的收益和風險進行分析

目錄

一、股票收益率

1、股票的日收益率

(1)計算股票的日收益率

(2)繪製股票的日收益率的時間序列圖

(3)日收益率均值計算

(4)日收益率的數據分佈

(5)累計日收益率計算

2、股票的平均年化收益率

二、股票的風險性衡量

1、極差、四分位差、平均差、方差、標準差和離散係數計算

2、偏度

3、峯度

(1)峯度的計算

(2)峯度與正態分佈的繪圖比較

4、日收益率分佈的正態性檢驗

5、股票的波動率計算


一、股票收益率

1、股票的日收益率

(1)計算股票的日收益率

日收益率計算公式如下:

該公式可理解爲兩天的價格差除以前一天的價格,下面提供兩種方法計算日收益率。

第一種,在 pandas 中,使用 .pct_change() 方法來計算日收益率。

## 讀取excel文件,並將‘日期’列解析爲日期時間格式,並設爲索引
stock_data=read_excel('stock_data/600000.SH.xlsx',parse_dates=['日期'],index_col='日期')
stock_data.drop('交易日期', axis=1, inplace=True) #刪除第二列’交易日期
#對股票數據的列名重新命名
stock_data.columns=['open','high','low','close','volume','market_value','turnover','pe','pb']
stock_data.index.name='date' #日期爲索引列
#將數據按日期這一列排序(保證後續計算收益率的正確性)
stock_data=stock_data.sort_values(by='date')
# 增加一列'earn_rate', 存儲每日的收益率
stock_data['earn_rate'] = stock_data['close'].pct_change()
# 打印數據的前5行
print(stock_data.head())

第二種,直接按公式計算日收益率。

stock_data['earn_rate'] =(stock_data['close']-stock_data['close'].shift(1))/stock_data['close'].shift(1)
print(stock_data.head())

兩種方法的結果相同,如下:

數據框增加了 earn_rate 一列,即股票的日收益率。注意第一天的收益率是缺失值 NaN,因爲沒有前一天的數據用於計算。爲了後續計算方便,我們選取 earn_rate 這一列,並將缺失值丟棄,存儲在新的變量 earn_rate_data中。使用 .dropna() 方法來刪除缺失值。

earn_rate_data=stock_data['earn_rate'].dropna()
#打印earn_rate_data的前5行
print(earn_rate_data.head())

結果爲:

 注意:計算對數收益率可以使你更好地瞭解回報隨時間的增長。可以使用如下代碼計算對數收益率:

stock_data['earn_rate']=np.log((stock_data['close']/stock_data['close'].shift(1)))

(2)繪製股票的日收益率的時間序列圖

繪製股票從2013年到2019年的日收益率的時間序列圖

earn_rate_data.plot(grid=True,color='green',label='600000.SH')
plt.title('2013-2019 earn rate of every day')
plt.ylabel('earn rate', fontsize='8')
plt.xlabel('date', fontsize='8')
#plt.ylim(0,0.3)  #可以繪製y軸的刻度範圍
plt.legend(loc='best',fontsize='small')
plt.show()

(3)日收益率均值計算

均值是最常用的統計量,它將一串數據平均後濃縮爲一個數值,但同時也丟失了數據波動性的信息。可使用 numpy 包中的 mean() 函數計算股票歷史收益的均值。

# 計算股票的日平均收益
earn_mean_daily = np.mean(earn_rate_data)
print("日平均收益:", earn_mean_daily)

(4)日收益率的數據分佈

繪製日收益率的直方圖可瞭解其分佈情況,同時也能觀察到日收益率中的異常值。一般在收益分佈的兩側有兩條長長的尾巴,在投資時一般會盡量避免左側尾巴上的異常值,因爲他們代表了較大的虧損;而分佈在右側尾巴上的異常值通常是件好事,它代表較大的盈利。

使用 matplotlib 繪圖包中的 hist()函數繪製直方圖。

# 繪製直方圖
plt.hist(earn_rate_data, bins=75)
plt.show()

其中,橫軸表示日收益率,縱軸表示出現的次數(即頻數)。

(5)累計日收益率計算

累積日收益率有助於定期確定投資價值。可以使用每日百分比變化的數值來計算累積日收益率,只需將其加上1並計算累積的乘積。累計日收益率計算並繪圖代碼如下:

stock_data['accumulate']=(1+stock_data['earn_rate']).cumprod()
stock_data['accumulate'].plot()
plt.legend()
plt.show()

 

2、股票的平均年化收益率

日收益率轉換爲年化收益率(一般假設一年252個交易日),其中μ是日平均收益率。

平均年化收益率計算公式如下:

earn_rate_year=(1+np.mean(earn_rate_data))**252-1
print("平均年化收益率:",earn_rate_year)

二、股票的風險性衡量

金融市場的風險是對不確定性的度量,反應在收益的波動上。一般可用以下統計量來表示:極差、四分位差、平均差、方差、標準差和離散係數;偏度;峯度等。

1、極差、四分位差、平均差、方差、標準差和離散係數計算

極差:極差爲數據樣本中的最大值與最小值的差值,是所有方式中最爲簡單的一種,它反應了數據樣本的數值範圍,是最基本的衡量數據離散程度的方式,受極值影響較大。

四分位差:即數據樣本的上四分之一位和下四分之一位的差值,反應了數據中間50%部分的離散程度,其數值越小表明數據越集中,數值越大表明數據越離散,同時由於中位數位於四分位數之間,故四分位差也反應出中位數對於數據樣本的代表程度,越小代表程度越高,越大代表程度越低。

平均差:各變量值與平均值的差的絕對值之和除以總數n,平均差以平均數爲中心,能全面準確的反應一組數據的離散狀況,平均差越大,說明數據離散程度越大,反之,離散程度越小。

方差:方差是各變量與平均值的差的平方和除以總數n-1,對數據離散程度的度量。

標準差:標準差又稱均方差,是方差的算數平方根。投資回報中較高的標準差意味着較高的風險,因爲數據分佈離均值更遠了,收益的波動幅度更大。方差與標準差都能很好的反應數據的離散程度。

離散係數:即變異係數,爲一組數據的標準差與平均數之比。針對不同數據樣本的標準差和方差,因數據衡量單位不同其結果自然無法直接進行對比,爲出具一個相同的衡量指標,則進行了離散係數的計算。

日收益率極差、四分位差、方差、標準差和離散係數的計算如下:

earn_rate_range=np.max(earn_rate_data)-np.min(earn_rate_data)
earn_rate_interquartile_range=earn_rate_data.quantile(0.75)-earn_rate_data.quantile(0.25)
earn_rate_var=np.var(earn_rate_data)
earn_rate_std=np.std(earn_rate_data)
earn_rate_coefficient=np.std(earn_rate_data)/np.mean(earn_rate_data)
print("日收益率極差:",earn_rate_range)
print("日收益率四分位差: ",earn_rate_interquartile_range)
print("日收益率方差: ",earn_rate_var)
print("日收益率標準差: ",earn_rate_std)
print("日收益率離散係數: ",earn_rate_coefficient)

 將標準差乘以交易日數目的平方根,得到年化標準差。將年化標準差平方,就得到年化方差。即:年化收益率均值、年化收益率方差、年化收益率標準差和年化收益率離散係數計算如下:

earn_mean_year=(1+np.mean(earn_rate_data))**252-1
earn_var_year=np.std(earn_rate_data)**2*252
earn_std_year=np.std(earn_rate_data)*np.sqrt(252)
earn_coefficient_year=earn_std_year/earn_mean_year
print("年收益率均值:",earn_mean_year)
print("年收益率方差: ",earn_var_year)
print("年收益率標準差: ",earn_std_year)
print("年收益率離散係數: ",earn_coefficient_year)

2、偏度

偏度(skewness),是統計數據分佈偏斜方向和程度的度量,是統計數據分佈非對稱程度的數字特徵。定義上偏度是樣本的三階標準化矩

偏度衡量隨機變量概率分佈的不對稱性,是相對於平均值下對稱程度的度量。偏度爲零表示數值相對均勻的分佈在平均值的兩側,但不一定意味着一定是對稱分佈。

 

 偏度定義中包括正態分佈(偏度=0),右偏分佈(也叫正偏分佈,其偏度>0),左偏分佈(也叫負偏分佈,其偏度<0)。

在金融領域,人們更傾向於正的偏度,因爲這意味着高盈利的概率更大。可使用 scipy.stats 提供的 skew() 函數計算收益率分佈的偏度,也可以直接使用pandas的函數。

from scipy import stats
# 計算收益分佈的偏度
earn_rate_skew=stats.skew(earn_rate_data)
print("日收益率偏度:",earn_rate_skew)
print("日收益率偏度:",earn_rate_data.skew())

經過偏度的計算,可以看出它具有稍許的負偏度。

3、峯度

(1)峯度的計算

峯度(kurtosis)又稱峯態係數。峯度表徵概率密度分佈曲線在平均值處峯值高低的特徵數,反映了峯部的尖度。。隨機變量的峯度計算方法爲:隨機變量的四階中心矩與方差平方的比值減3。(減3是爲了讓正態分佈的峯度爲0)

這個統計量需要與正態分佈相比較,峯度爲0表示該總體數據分佈與正態分佈的陡緩程度相同;峯度大於0表示該總體數據分佈與正態分佈相比較爲陡峭,爲尖頂峯;峯度小於0表示該總體數據分佈與正態分佈相比較爲平坦,爲平頂峯。峯度的絕對值數值越大表示其分佈形態的陡緩程度與正態分佈的差異程度越大。

 下面公式也程爲超值峯度:

在實際應用中,通常將峯度值做減3處理,使得正態分佈的峯度0。因此,在使用統計軟件進行計算時,應注意該軟件默認的峯度值計算公式。如Eviews默認的正態分佈峯度爲3。

因爲正態分佈的峯度是3,所以將超出3的部分稱爲超值峯度。大部分金融收益都具有正的超值峯度。可以使用scipy.stats提供的 kurtosis() 函數計算分佈的超值峯度,也可以使用pandas的函數。

from scipy import stats
# 計算收益分佈的偏度
earn_rate_kurtosis=stats.kurtosis(earn_rate_data)
print("日收益率峯度:",earn_rate_kurtosis)
print("日收益率峯度:",earn_rate_data.kurt())

 上述峯度的計算結果表明,該股票日收益率的峯比正態分佈高得多。

(2)峯度與正態分佈的繪圖比較

我們通過下圖概率密度分佈的比較看出來,圖中橙色代表日收益率的分佈,藍色表正態分佈。

# 模擬正態分佈數據,其均值和標準差與文中的股票的日收益率相同。
mu=np.mean(earn_rate_data)
sigma=np.std(earn_rate_data)
norm=np.random.normal(mu,sigma,size=10000)
# 繪製正態分佈的概率密度分佈圖
plt. hist(norm, bins=100, alpha=0.8, density=True, label='Normal Distribution')

# 繪製收益的概率密度分佈圖
plt.hist(earn_rate_data, bins=75, alpha=0.7, density=True,label='earn_rate Distribution')
plt.legend()
plt.show()

4、日收益率分佈的正態性檢驗

首先,正態分佈是對稱的,其偏度爲0,而該股票日收益率具有負的偏度-0.280;其次,正態分佈的峯度是3,而該股票收益的峯度高達8.95。從這兩個統計量看出,該股票日收益率並不是正態分佈,它稍微向左偏斜,並且具有比較尖的峯。

爲了判斷股票收益分佈的正態性,我們需要使用真正的統計檢驗方法,而不是簡單地檢查峯度或偏度。

這裏使用 scipy.stats 提供的 shapiro() 函數,對股票收益分佈進行 Shapiro-Wilk 檢驗。該函數有兩個返回值,一個是檢驗的 t 統計量,另一個是 p 值。它越接近1就越表明數據和正態分佈擬合得越好。

# 從 scipy.stats 導入shapiro
from scipy.stats import shapiro
# 對股票收益進行Shapiro-Wilk檢驗
shapiro_results = shapiro(earn_rate_data)
print("Shapiro-Wilk檢驗結果: ", shapiro_results)
# 提取P值
p_value = shapiro_results[1]
print("P值: ", p_value)

5、股票的波動率計算

股票的波動率衡量了股票在特定時間內收益率的變化。常常將一隻股票的波動率和另一隻股票比較,以尋找風險較小的股票;或是將之與市場指數比較,來檢查股票在整個市場上的波動。

一般來說,波動率越高,該股票的投資風險更大,導致人們選擇投資其他股票。

通過計算股票百分比變化的移動窗口標準差得到波動率。可以使用以下代碼計算並繪圖:

# 定義最小週期
min_periods = 75
# 計算波動率
vol = stock_data['earn_rate'].rolling(min_periods).std() * np.sqrt(min_periods)
# 繪製波動率曲線
vol.plot(grid=True)
# 顯示繪圖結果
plt.show()

 

注意:窗口的大小能夠改變整體的結果:如果擴大窗口(也就是讓min_periods變大),結果將變得不那麼有代表性。如果縮小窗口,結果將更接近於標準差。考慮到所有這些,你會發現基於數據採樣頻率得到合適的窗口大小絕對是一項技能。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章