Python数据分析之股票实战

前言:对于股票的研究我想,无论是专业人士还是非专业人士都对其垂涎已久,因为我们都有赌徒的心态,我们都希望不花太多的时间但是能赚足够的钱,而股票绝对是一个好的选择,本人也不例外对股票垂涎已久,不管你是否承认股票是一个来钱快的地方,但是伴随着的当然是巨大的风险,毕竟这么多炒股,并不是每个人都赚到了钱,下面的内容也不一定保证你一定能赚到钱,反正都是“猜”,不如让“猜”看起来更加专业一些。

原文章参考:http://nbviewer.ipython.org/github/jmportilla/Udemy-notes/blob/master/Data%20Project%20-%20Stock%20Market%20Analysis.ipynb

首先当然是导入我们需要的模块了

import pandas as pd
from pandas import Series,DataFrame
import numpy as np

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("whitegrid")
%matplotlib inline

from pandas.io.data import DataReader
from datetime import datetime
from __future__ import division

注:其实国内的股票相关行情可以通过tushare这个库获取,但是碍于自己已经对着原文自己演练了一遍了,图都已经截好了,也就没有将股票中国化,分析的主要是AAPL,GOOG,MSFT,AMZN,数据来自Yahoo。

tushare相关信息参考:http://tushare.waditu.com/

###股票代码
stock_lis = ["AAPL","GOOG","MSFT","AMZN"]

###开始及结束时间,这里我们去最近一年的数据
end = datetime.now()
start = datetime(end.year - 1,end.month,end.day)

###将每个股票的近一年行情遍历出来
for stock in stock_lis:
    globals()[stock] = DataReader(stock,"yahoo",start,end)

看看前面五条信息

AAPL.head()
AAPL.describe()
AAPL.info()

DatetimeIndex: 252 entries, 2014-11-10 00:00:00 to 2015-11-09 00:00:00 Data columns (total 6 columns): Open 252 non-null float64 High 252 non-null float64 Low 252 non-null float64 Close 252 non-null float64 Volume 252 non-null int64 Adj Close 252 non-null float64 dtypes: float64(5), int64(1) memory usage: 13.8 KB

画一下每日调整收盘价的走势图

注:每日收盘价http://baike.baidu.com/link?url=plkht9HaMdpNPI2lFUsUvgYhjdYvqOlSStjrDvqQxhuHuA5Iaww_FVitVXEqp_ne0DATpwtuBKeSUPK8I1t4ka

AAPL["Adj Close"].plot(legend=True,figsize=(10,4))
###每日成交量
AAPL["Volume"].plot(legend=True,figsize=(10,4))

下面两个链接有关移动平均线的一些说明

1.) http://www.investopedia.com/terms/m/movingaverage.asp 2.) http://www.investopedia.com/articles/active-trading/052014/how-use-moving-average-buy-stocks.asp

当然也可以瞧瞧百度百科:http://baike.baidu.com/view/7973.htm

注:在tushare这个模块里获取的国内行情的相关信息就已经包揽了常用的均线了,非常赞!

参考:http://tushare.waditu.com/trading.html

import tushare as tsts.get_hist_data('600848') #一次性获取全部日k线数据

结果显示:

             open    high   close     low     volume    p_change  ma5 \
date
2012-01-11   6.880   7.380   7.060   6.880   14129.96     2.62   7.060
2012-01-12   7.050   7.100   6.980   6.900    7895.19    -1.13   7.020
2012-01-13   6.950   7.000   6.700   6.690    6611.87    -4.01   6.913
2012-01-16   6.680   6.750   6.510   6.480    2941.63    -2.84   6.813
2012-01-17   6.660   6.880   6.860   6.460    8642.57     5.38   6.822
2012-01-18   7.000   7.300   6.890   6.880   13075.40     0.44   6.788
2012-01-19   6.690   6.950   6.890   6.680    6117.32     0.00   6.770
2012-01-20   6.870   7.080   7.010   6.870    6813.09     1.74   6.832

             ma10    ma20      v_ma5     v_ma10     v_ma20     turnover
date
2012-01-11   7.060   7.060   14129.96   14129.96   14129.96     0.48
2012-01-12   7.020   7.020   11012.58   11012.58   11012.58     0.27
2012-01-13   6.913   6.913    9545.67    9545.67    9545.67     0.23
2012-01-16   6.813   6.813    7894.66    7894.66    7894.66     0.10
2012-01-17   6.822   6.822    8044.24    8044.24    8044.24     0.30
2012-01-18   6.833   6.833    7833.33    8882.77    8882.77     0.45
2012-01-19   6.841   6.841    7477.76    8487.71    8487.71     0.21
2012-01-20   6.863   6.863    7518.00    8278.38    8278.38     0.23

这里的平均线是通过自定义函数,手动设置的,主要是10,20,50日均线

###移动平均线:
ma_day = [10,20,50]

for ma in ma_day:
    column_name = "MA for %s days" %(str(ma))
    AAPL[column_name] = pd.rolling_mean(AAPL["Adj Close"],ma)

瞧瞧效果

AAPL[10:15]

默认subplots这个参数是False的,这里我们瞧瞧True的情况

AAPL[["Adj Close","MA for 10 days","MA for 20 days","MA for 50 days"]].plot(subplots=True)
AAPL[["Adj Close","MA for 10 days","MA for 20 days","MA for 50 days"]].plot(figsize=(10,4))

很好看有没有!!!

让我们新建一个字段叫做“Dailly Return”,注意Dailly其实我写错了,Dailly Return其实是每日较于前一日的涨幅率.

AAPL["Dailly Return"] = AAPL["Adj Close"].pct_change()
###plot一下
AAPL["Dailly Return"].plot(figsize=(10,4),legend=True)
###这里我们改变一下线条的类型(linestyle)以及加一些标记(marker)
AAPL["Dailly Return"].plot(figsize=(10,4),legend=True,linestyle="--",marker="o")
###再来瞧瞧核密度评估图吧,这里吧Nan指给drop掉
sns.kdeplot(AAPL["Dailly Return"].dropna())

注:This function combines the matplotlib hist function (with automatic calculation of a good default bin size) with the seaborn kdeplot() and rugplot() functions.

由官方说明可知,displot函数是由直方图与seaborn的核密度图以及rugplot(Plot datapoints in an array as sticks on an axis.)组合

###plot一下
sns.distplot(AAPL["Dailly Return"].dropna(),bins=100)
###再来单独获取一下每个公司的调整收盘价记录
closing_df = DataReader(stock_lis,"yahoo",start,end)["Adj Close"]
closing_df.head()
###将每个公司的每日收盘价的百分数变化,及涨幅或者降幅,通过这个我们可以评估它的涨幅前景
tech_rets = closing_df.pct_change()
tech_rets.head()
###平均值都是大于0的,不错
tech_rets.mean()

AAPL 0.000456 AMZN 0.003203 GOOG 0.001282 MSFT 0.000623 dtype: float64

我们来瞧瞧jointplot这个函数,通过这个函数我们可以画出两个公司的”相关性系数“,或者说皮尔森相关系数(http://baike.baidu.com/view/3028699.htm),如下图所示

如果你看过《大数据时代》这本书,你就会知道为什么作者会求两个公司的相关性了,书中有提到的一个观点是,在大数据时代的到来,我们可以通过大数据来描绘事物之间的相关性并预测,而为什么,是后面要研究的事,注重相关性而不是因果关系。(个人读后感,如有偏驳还望指正)

下面这一部分主要在说相关性~

sns.jointplot("GOOG","GOOG",tech_rets,kind="hex")

如上图所示,我们画出的事google与google自己的皮尔森相关系数,当然是1啦!值得说明的皮尔森相关系数的值在-1到1之间,1代表正相关,-1代表负相关,0代表没有任何相关性,有兴趣了解怎么算的,参考:https://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient

sns.jointplot("GOOG","GOOG",tech_rets,kind="scatter")

注:上面两张图画的是同一件事物,不过我们kind指定的不同,分别是六边形hex,散点scatter

我们再来画画Google与微软的皮尔森相关系数吧

sns.jointplot("GOOG","MSFT",tech_rets,kind="scatter")

下面是一些相关知识,有兴趣可以瞧瞧

如何计算协方差:

http://zh.wikihow.com/%E8%AE%A1%E7%AE%97%E5%8D%8F%E6%96%B9%E5%B7%AE

如何计算百分比变化:

http://zh.wikihow.com/%E8%AE%A1%E7%AE%97%E7%99%BE%E5%88%86%E6%AF%94%E5%8F%98%E5%8C%96

什么是Pearson product-moment:

https://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient

我们再来瞧瞧pairplot这个函数吧,四个公司的行情一起比较。

官方说明:Plot pairwise relationships in a dataset. By default, this function will create a grid of Axes such that each variable in data will by shared in the y-axis across a single row and in the x-axis across a single column. The diagonal Axes are treated differently, drawing a plot to show the univariate distribution of the data for the variable in that column. It is also possible to show a subset of variables or plot different variables on the rows and columns.

该函数用于成对的比较不同数据集之间的相关性,而对角线则会显示该数据集的直方图,详情见下图呗,一图抵前言

至于从形态看出相关性,你可能得看看Wikipedia了

sns.pairplot(tech_rets.dropna())

再来瞧瞧Pairplot这个对象

###我们指画直方图
returns_fig = sns.PairGrid(tech_rets.dropna())
returns_fig.map_diag(plt.hist,bins=30)
returns_fig = sns.PairGrid(tech_rets.dropna())

###右上角画散点图
returns_fig.map_upper(plt.scatter,color="purple")

###左下角画核密度图
returns_fig.map_lower(sns.kdeplot,cmap="cool_d")

###对角线的直方图
returns_fig.map_diag(plt.hist,bins=30)

再瞧瞧corrplot这个函数,官方我也敲不到它的说明,主要画相关系数,如下

###annot设定是否注释
sns.corrplot(tech_rets.dropna(),annot=False)
sns.corrplot(tech_rets.dropna(),annot=True)

在下面这一部分主要说风险这一部分了,比如推测最多亏多少钱~~

首先瞧瞧各数值吧

rets = tech_rets.dropna()

###平均值
rets.mean()

AAPL 0.000456 AMZN 0.003203 GOOG 0.001282 MSFT 0.000623 dtype: float64

###标准差  参考:http://baike.baidu.com/view/78339.htm
rets.std()

AAPL 0.016738 AMZN 0.021165 GOOG 0.018484 MSFT 0.017800 dtype: float64

###点的大小
area = np.pi *20

###分别以rets的平均值,标准差为xy轴
plt.scatter(rets.mean(),rets.std())

###分别设定xy轴的标注
plt.xlabel("Expected Return")
plt.ylabel("Risk")

for label,x,y in zip(rets.columns,rets.mean(),rets.std()):
    plt.annotate(
        label,
        xy = (x,y),xytext = (50,50),
        textcoords = "offset points",ha = "right",va = "bottom",
        arrowprops = dict(arrowstyle = "-",connectionstyle = "arc3,rad=-0.3"))

由上面我们可以看出AMZN亚马逊的预计收益要高于其他三家公司,但是风险值也要高于其他三家公司~这是怎么看出来的呢?

摘自百度百科(http://baike.baidu.com/view/78339.htm):在投资基金上,一般人比较重视的是业绩,但往往买进了近期业绩表现最佳的基金之后,基金表现反而不如预期,这是因为所选基金波动度太大,没有稳定的表现。 衡量基金波动程度的工具就是标准差(Standard Deviation)。标准差是指基金可能的变动程度。标准差越大,基金未来净值可能变动的程度就越大,稳定度就越小,风险就越高

而期待收益值就是我们在上面说到过的每日涨幅度,这四家公司近一年而言每日的更改幅度的平均值都是大于零的,说明至少是涨着的。

而怎么标出图上的效果参考下面matplotlib的官方说明

Matplotlib的注释详情参考:http://matplotlib.org/users/annotations_guide.html

如何计算标准差:

http://zh.wikihow.com/%E8%AE%A1%E7%AE%97%E5%9D%87%E5%80%BC%E3%80%81%E6%A0%87%E5%87%86%E5%B7%AE%E5%92%8C%E6%A0%87%E5%87%86%E8%AF%AF%E5%B7%AE

什么是标准差,及其意思:

http://baike.baidu.com/link?url=XOhnnn6npvQejz5raELJIvSLYxJZV75w1Gxf4DqRajcqWNzhhTFi7rbkoOQnBzEVtg8_GWdfamnrSM0sooBoQa

摘录:标准差应用于投资上,可作为量度回报稳定性的指标。标准差数值越大,代表回报远离过去平均数值,回报较不稳定故风险越高。相反,标准差数值越小,代表回报较为稳定,风险亦较小。

蒙特卡洛评估

在应用蒙特卡洛评估之前,先看看这些股票的基本。

sns.distplot(AAPL['Dailly Return'].dropna(),bins=100,color='purple')
closing_df.tail()
closing_df.head()

再来瞧瞧Quantile,这个我也没太看懂,什么置信区间,如有了解还望指教

什么是百位分数参考:http://www.itongji.cn/article/0ZRJ52013.html

rets['AMZN'].quantile(0.05)

-0.021360026714234592

上面的结果说明,我们95%的置信,一天我们不会损失超过0.02160…

days = 365

dt = 1/days

mu = rets.mean()["GOOG"]

sigma = rets.std()["GOOG"]

np.random.normal(loc = 0,scale=1)
        1.294219218586235

1234567

GOOG.head()
这么一大串就是蒙特卡洛的推算了

def stock_monte_carlo(start_price,days,mu,sigma):

    price = np.zeros(days)
    price[0] = start_price

    shock = np.zeros(days)
    drift = np.zeros(days)

    for x in xrange(1,days):

        shock[x] = np.random.normal(loc=mu * dt,scale=sigma * np.sqrt(dt))

        drift[x] = mu * dt

        price[x] = price[x-1] + (price[x-1] *(drift[x] + shock[x]))

    return price


start_price = 548.49

for run in xrange(100):
    plt.plot(stock_monte_carlo(start_price,days,mu,sigma))

#ax = plt.gca()
#ax.ticklabel_format(useOffset=True)
plt.xlabel("Days")
plt.ylabel("Price")

plt.title("Monte Carlo Analysis for Google")
runs = 10000

simulations = np.zeros(runs)

for run in xrange(runs):
    simulations[run] = stock_monte_carlo(start_price,days,mu,sigma)[days-1]

q = np.percentile(simulations,1)

plt.hist(simulations,bins=200)

plt.figtext(0.6,0.8,s="Start price: $%.2f" % start_price)

plt.figtext(0.6,0.7,"Mean final price: $%s" %simulations.mean())

plt.figtext(0.15,0.6,"q(0.99: $%.2f)" %q)

plt.axvline(x=q,linewidth=4,color="r")

plt.title(u"Final price distribution for Google stock after %s days" %days,weight="bold")

下面是一些本人整理的参考资料

什么是Quantile:

https://en.wikipedia.org/wiki/Quantile

Monte Carlo Simulation With GBM:

http://www.investopedia.com/articles/07/montecarlo.asp

The Uses And Limits Of Volatility:

http://www.investopedia.com/articles/04/021804.asp

An Introduction To Value at Risk (VAR):

http://www.investopedia.com/articles/04/092904.asp

什么是什么是百分位数:

http://www.itongji.cn/article/0ZRJ52013.html

Np.percentile:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.percentile.html

Np.random.normal:normal distribution###正态分布

http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.normal.html

置信区间:Confidence interval

http://baike.baidu.com/link?url=Hay8cf0XTZrn8Z-d9wCw5voh5pKkJCo_yK7rqE4NUlsZ7ws5mhqvNIMwM05x61rbhz948jGLdd4D-iwfmRZ-

分位数:

http://baike.baidu.com/link?url=Kx00dMbt4gAuEo8O-0nTk2_mb1RQ3rEYKzsp_ifBUTJU8-LTh-9tpXfnfqFjeSnpxlhzcYT_RC3irYhEsQgUoa

摘录:设连续随机变量X的分布函数为F(X),密度函数为p(x)。那么,对任意0<p<1的p,称F(X)=p的X为此分布的分位数,或者下侧分位数。简单的说,分位数指的就是连续分布函数中的一个点,这个点的一侧对应概率p。

时间序列分位数回归模型的实证分析:

http://www.docin.com/p-757019312.html

基于分位数回归的股票市场规模效应分析:

http://www.docin.com/p-1011466794.html

原文链接:http://youerning.blog.51cto.com/10513771/1712775

原文发布于微信公众号 - CDA数据分析师(cdacdacda)

原文发表时间:2016-11-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

python数据分析之股票实战

对于股票的研究我想,无论是专业人士还是非专业人士都对其垂涎已久,因为我们都有赌徒的心态,我们都希望不花太多的时间但是能赚足够的钱,而股票绝对是一个好的选择,本人...

2.8K6
来自专栏后端技术探索

算法之经典背包问题分析与实例

我们人类是一种贪婪的动物,如果给您一个容量一定的背包和一些大小不一的物品,裝到背包里面的物品就归您,遇到这种好事大家一定不会错过,用力塞不一定是最好的办法,...

981
来自专栏新智元

邓侃:谷歌Talk to books引爆搜索方式革命

?---- 【新智元导读】昨天,新智元介绍了谷歌的全新搜索工具“Talk to Books”,基于自然语言文本理解,用户能够凭语义而非关键词来实现搜索功能。谷歌...

2966
来自专栏WOLFRAM

用 Wolfram 语言制作圣诞动画

2212
来自专栏阮一峰的网络日志

布尔代数入门

布尔代数是计算机的基础。没有它,就不会有计算机。 布尔代数发展到今天,已经非常抽象,但是它的核心思想很简单。本文帮助你理解布尔代数,以及为什么它促成了计算机的诞...

3236
来自专栏数据结构与算法

1023 GPA计算

1023 GPA计算  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 青铜 Bronze 题解  查看运行结果 题目描述 Descrip...

2915
来自专栏AI研习社

问答 | 深度置信网与堆栈自编码器有什么区别?

2892
来自专栏PPV课数据科学社区

【陆勤笔记】《深入浅出统计学》6排列与组合:排序、排位、排列

点击上方 “蓝色字” 可关注我们! 作者:王陆勤 顺序有时候很重要。《大学》里面有言:物有本末,事有终始,知所先后,则近道矣。 计算排位 ? 推导出用于重复排列...

2829
来自专栏我和未来有约会

[Silverlight动画]转向行为 - 群落

说到群落,很难不引用Craig Reynolds和他的"boilds"模拟系统。Reynolds很牛的将一个看似非常恐怖的复杂过程,拆成了几个比较简单的行为。 ...

2258
来自专栏数据科学与人工智能

【机器学习】机器学习大白话

买芒果 嘴馋的你想吃芒果了,于是你走到水果摊,挑了几个让老板过过秤,然后你再根据芒果的斤两付钱走人。 显然,买芒果你当然是挑着最甜、最熟的来买(因为你是根据重量...

2615

扫码关注云+社区

领取腾讯云代金券