用python炒股效益怎样_用Python分析股票的收益和风险

本文将用Python编程,带你了解股票投资收益和风险的基本知识。

一、股票的收益

1.1 导入CSV时序数据

本文将分析微软2000年以来的股票交易数据(点我下载哦),它是一个 csv 格式的时间序列数据。你将使用 pandas 读取 csv 数据,并存储为DataFrame格式。

# 导入pandas包

import pandas as pd

# 读取csv文件,并将‘Date’列解析为日期时间格式,并设为索引

StockPrices = pd.read_csv('MSFTPrices.csv', parse_dates=['Date'], index_col='Date')

# 将数据按日期这一列排序(保证后续计算收益率的正确性)

StockPrices = StockPrices.sort_values(by='Date')

# 打印数据的前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

该股票数据包括了交易日期、开盘价、最高价、最低价、收盘价、调整后的收盘价以及成交量。其中调整后的收盘价最为重要,它对股票分割、股息和其他公司行为进行了标准化,能真实地反映股票随时间的回报。所以本文后续的计算都是基于调整后的收盘价(Adjusted)这一列数据。

1.2 计算收益率

收益率的计算公式如下:

math?formula=R_%7Bt2%7D%20%3D%20%5Cfrac%7BP_%7Bt2%7D%20-%20P_%7Bt1%7D%7D%7BP_%7Bt1%7D%7D

这里可理解为两天的价格差除以前一天的价格。在 pandas 中,使用 .pct_change() 方法来计算收益率。

# 增加一列'Returns', 存储每日的收益率

StockPrices['Returns'] = StockPrices['Adjusted'].pct_change()

# 检查前5行数据

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

数据框增加了 Returns 一列,即股票的收益。注意第一天的收益率是缺失值 NaN,因为没有前一天的数据用于计算。

为了后续计算方便,我们选取 Returns 这一列,并将缺失值丢弃,存储在新的变量 clean_returns 中。使用 .dropna() 方法来删除缺失值。

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

绘制每日收益随时间变化的图。

# 导入matplotlib绘图包中的pyplot模块

import matplotlib.pyplot as plt

#绘图

clean_returns.plot()

plt.show()

b22bd9a587a2

1.3 收益的均值

均值是最常用的统计量,它将一串数据平均后浓缩为一个数值,但同时也丢失了数据波动性的信息。

可使用 numpy 包中的 mean() 函数计算股票历史收益的均值。

# 导入numpy包

import numpy as np

# 计算股票的日平均收益

mean_return_daily = np.mean(clean_returns)

print("日平均收益:", mean_return_daily)

日平均收益: 0.00037777546435757725

通过以下公式,将日收益率转换为年化收益率(一般假设一年252个交易日),其中

math?formula=%5Cmu 是日平均收益率。

math?formula=%E5%B9%B3%E5%9D%87%E5%B9%B4%E5%8C%96%E6%94%B6%E7%9B%8A%E7%8E%87%20%3D(1%2B%5Cmu)%5E%7B252%7D%E2%88%921

# 计算平均年化收益

mean_return_annualized = ((1 + mean_return_daily)**252) - 1

print("平均年化收益:", mean_return_annualized)

平均年化收益: 0.09985839482858783

1.4 收益的分布

绘制收益的直方图可了解其分布情况,同时也能观察到收益中的异常值。一般在收益分布的两侧有两条长长的尾巴,在投资时一般会尽量避免左侧尾巴上的异常值,因为他们代表了较大的亏损;而分布在右侧尾巴上的异常值通常是件好事,它代表较大的盈利。

使用 matplotlib 绘图包中的 hist()函数绘制直方图。

# 绘制直方图

plt.hist(clean_returns, bins=75)

plt.show()

b22bd9a587a2

上图所示的收益是个怎样的分布呢?是正态分布吗?我们将在后续揭晓答案。

二、风险的衡量

金融市场的风险是对不确定性的度量,反应在收益的波动上。一般可用以下统计量来表示:

方差或标准差

偏度

峰度

接下来我们将逐个计算它们。

2.1 方差

方差是对数据离散程度的度量。下图中蓝色分布比红色分布的方差大得多,其数据也更加分散。

b22bd9a587a2

图片来源:https://en.wikipedia.org/wiki/Standard_deviation

标准差又称均方差,是方差的算数平方根。投资回报中较高的标准差意味着较高的风险,因为数据分布离均值更远了,收益的波动幅度更大。

可使用 numpy 包中的 std() 函数计算标准差

math?formula=%5Csigma,方差则是标准差的平方

math?formula=%5Csigma%5E2.

# 计算标准差

sigma_daily = np.std(clean_returns)

print("标准差: ", sigma_daily)

# 计算方差

variance_daily = sigma_daily ** 2

print("方差: ", variance_daily)

标准差: 0.019341100408708328

方差: 0.0003740781650197374

以上计算的是每日的方差,我们可以将之转化成年化方差。将标准差乘以交易日数目的平方根,得到年化标准差。将年化标准差平方,就得到年化方差。

# 计算年化标准差

sigma_annualized = sigma_daily*np.sqrt(252)

print("年化标准差:", sigma_annualized)

# 计算年化方差

variance_annualized = sigma_annualized ** 2

print("年化方差:", variance_annualized)

年化标准差: 0.3070304505826317

年化方差: 0.09426769758497383

2.2 偏度

偏度是数据分布偏斜方向和程度的度量,反应分布的非对称性。

下图所示的曲线分别代表了负偏态和正偏态。在金融领域,人们更倾向于正的偏度,因为这意味着高盈利的概率更大。

b22bd9a587a2

图片来源:https://en.wikipedia.org/wiki/Skewness

可使用 scipy.stats 提供的 skew() 函数计算收益分布的偏度。

# 从 scipy.stats 导入skew函数

from scipy.stats import skew

# 计算收益分布的偏度

returns_skewness = skew(clean_returns)

print("偏度:", returns_skewness)

偏度: 0.21935459193067852

回顾之前绘制的收益分布图,乍看之下似乎是对称分布,但经过偏度的计算,我们知道它具有稍许的正偏度。

2.3 峰度

峰度表征概率密度分布曲线在平均值处峰值高低的特征数,反映了峰部的尖度。通常将样本的峰度和正态分布相比较,因为正态分布的峰度是3,所以将超出3的部分称为超值峰度。大部分金融收益都具有正的超值峰度。

b22bd9a587a2

kurtosis.png

使用scipy.stats提供的 kurtosis() 函数计算分布的超值峰度。

# 从 scipy.stats 导入 kurtosis 函数

from scipy.stats import kurtosis

# 计算收益分布的超值峰度

excess_kurtosis = kurtosis(clean_returns)

print("超值峰度:", excess_kurtosis)

# 计算峰度

fourth_moment = excess_kurtosis + 3

print("峰度:", fourth_moment)

超值峰度: 10.31457261802553

峰度: 13.31457261802553

上述峰度的计算结果表明,该股票收益的峰比正态分布高得多。我们也可通过下图概率密度分布的比较看出来,图中橙色代表收益的分布,而蓝色表正态分布。

# 模拟正态分布数据,其均值和标准差与文中的股票收益相同。

mu = mean_return_daily

sigma = sigma_daily

norm = np.random.normal(mu, sigma, size=10000)

# 绘制正态分布的概率密度分布图

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')

# 增加图例说明

plt.legend()

# 绘图

plt.show()

b22bd9a587a2

三、收益分布正态性检验

现在让我们回到第一部分结尾提出的问题:该股票的收益分布是正态分布吗?

我们知道正态分布是对称的,其偏度为0,而该股票收益具有正的偏度0.219。正态分布的峰度是3,而该股票收益的峰度高达13.31。从这两个统计量看出,该股票收益并不是正态分布,它稍微向右偏斜,并且具有比较尖的峰。

但是这就能让我们自信的下结论吗?为了判断股票收益分布的正态性,我们需要使用真正的统计检验方法,而不是简单地检查峰度或偏度。

这里使用 scipy.stats 提供的 shapiro() 函数,对股票收益分布进行 Shapiro-Wilk 检验。该函数有两个返回值,一个是检验的t统计量,另一个是p值。现在你并不需要知道 Shapiro-Wilk 检验到底是个什么鬼,只要知道如何使用p值判断数据的正态性:如果p值小于等于0.05,就拒绝正态性假设,得出数据非正态分布的结论。

# 从 scipy.stats 导入shapiro

from scipy.stats import shapiro

# 对股票收益进行Shapiro-Wilk检验

shapiro_results = shapiro(clean_returns)

print("Shapiro-Wilk检验结果: ", shapiro_results)

# 提取P值

p_value = shapiro_results[1]

print("P值: ", p_value)

Shapiro-Wilk检验结果: (0.9003633260726929, 0.0)

P值: 0.0

计算得到的p值非常小,在目前的精度下等于0,所以我们可以肯定地说该收益分布不是正态分布。

小结

本文用Python计算了股票的收益和风险,我们首先查看了股票的收益率及其分布,接着计算指示风险的统计量:方差、偏度和峰度,最后检验了收益分布的正态性。

另外我们还学到了以下统计函数:

import numpy as np

np.mean() # 均值

np.std() # 标准差

from scipy.stats import skew, kurtosis, shapiro

skew() # 偏度

kurtosis() # 超值峰度

shapiro() # Shapiro-Wilk检验正态性

如果你想自己下载股票数据的话,可以参考这篇文章 《如何用Python下载金融数据》。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值