第一步、获取数据

股市数据可以从Yahoo! Finance、 Google Finance以及国内的新浪财经等地方拿到。同时,pandas包提供了轻松从以上网站获取数据的方法。

import pandas as pd            # as 是对包或模块重命名
import pandas.io.data as web   # 导入包和模块,模块可能随着版本的不同会发生变化
import datetimeImportError: The pandas.io.data module is moved to a separate package (pandas-datareader).
After installing the pandas-datareader package (https://github.com/pydata/pandas-datareader),you can change the import ``from pandas.io import data, wb`` to ``from pandas_datareader import data, wb``.

pandas.io.data模块已换成独立的pandas-datareader包,所以上述代码会报错。

所以,在cmd命令行中执行以下语句即可解决这个问题:(安装pandas-datareader包

pip install pandas_datareader

所以新代码为下:

import pandas as pd
import pandas_datareader.data as web
import datetime
start = datetime.datetime(2016,1,1)
end = datetime.date.today()
apple = web.DataReader("AAPL", "yahoo", start, end)#  web.DataReader("AAPL", "yahoo", start, end)会出现下处错误
# Let's get Apple stock data; Apple's ticker symbol is AAPL
# First argument is the series we want, second is the source ("yahoo" for Yahoo! Finance), third is the start date, fourth is the end date会输出如下结果:
ImmediateDeprecationError:
Yahoo Daily has been immediately deprecated due to large breaks in the API without the
introduction of a stable replacement. Pull Requests to re-enable these data
connectors are welcome.

上述出现错误的原因是因为雅虎在中国受限制的原因,所以再一次修改代码, 这里我们需要引入另外一个模块‘fix_yahoo_finance’,同样使用pip方法在cmd命令中进行安装。

pip install fix_yahoo_finance

所以,代码如下:


import pandas_datareader.data as web
import datetime
import fix_yahoo_finance as yf
yf.pdr_override()start=datetime.datetime(2006, 1, 1)
end=datetime.datetime(2012, 1, 1)
apple=web.get_data_yahoo('AAPL',start,end)
appleapple.head()或者
start=datetime.datetime(2017, 1, 1)
end=datetime.datetime.today()
apple=web.get_data_yahoo('AAPL',start,end)
apple
Out[21]: Open        High         Low       Close   Adj Close  \
Date
2017-01-03  115.800003  116.330002  114.760002  116.150002  113.013916
2017-01-04  115.849998  116.510002  115.750000  116.019997  112.887413
2017-01-05  115.919998  116.860001  115.809998  116.610001  113.461502
2017-01-06  116.779999  118.160004  116.470001  117.910004  114.726402
2017-01-09  117.949997  119.430000  117.940002  118.989998  115.777237
2017-01-10  118.769997  119.379997  118.300003  119.110001  115.893997   

第二步、对提取的数据可视化:

import matplotlib.pyplot as plt   # Import matplotlib
# This line is necessary for the plot to appear in a Jupyter notebook
%matplotlib inline# Control the default size of figures in this Jupyter notebook
%pylab inlinepylab.rcParams['figure.figsize'] = (15, 9)   # Change the size of plotsapple["Adj Close"].plot(grid = True) # Plot the adjusted closing price of AAPL

第三步、画

线段图是可行的,但是每一天的数据至少有四个变量(开市,股票最高价,股票最低价和闭市),我们希望找到一种不需要我们画四条不同的线就能看到这四个变量走势的可视化方法。一般来说我们使用烛柱图(也称为日本阴阳烛图表)来可视化金融数据,烛柱图最早在18世纪被日本的稻米商人所使用。可以用matplotlib来作图,但是需要费些功夫。

你们可以使用我实现的一个函数更容易地画烛柱图,它接受pandas的data frame作为数据来源。(程序基于这个例子, 你可以从这里找到相关函数的文档。)

from matplotlib.dates import DateFormatter, WeekdayLocator,\DayLocator, MONDAY
from matplotlib.finance import candlestick_ohlcdef pandas_candlestick_ohlc(dat, stick = "day", otherseries = None):""":param dat: pandas DataFrame object with datetime64 index, and float columns "Open", "High", "Low", and "Close", likely created via DataReader from "yahoo":param stick: A string or number indicating the period of time covered by a single candlestick. Valid string inputs include "day", "week", "month", and "year", ("day" default), and any numeric input indicates the number of trading days included in a period:param otherseries: An iterable that will be coerced into a list, containing the columns of dat that hold other series to be plotted as linesThis will show a Japanese candlestick plot for stock data stored in dat, also plotting other series if passed."""mondays = WeekdayLocator(MONDAY)        # major ticks on the mondaysalldays = DayLocator()              # minor ticks on the daysdayFormatter = DateFormatter('%d')      # e.g., 12# Create a new DataFrame which includes OHLC data for each period specified by stick inputtransdat = dat.loc[:,["Open", "High", "Low", "Close"]]if (type(stick) == str):if stick == "day":plotdat = transdatstick = 1 # Used for plottingelif stick in ["week", "month", "year"]:if stick == "week":transdat["week"] = pd.to_datetime(transdat.index).map(lambda x: x.isocalendar()[1]) # Identify weekselif stick == "month":transdat["month"] = pd.to_datetime(transdat.index).map(lambda x: x.month) # Identify monthstransdat["year"] = pd.to_datetime(transdat.index).map(lambda x: x.isocalendar()[0]) # Identify yearsgrouped = transdat.groupby(list(set(["year",stick]))) # Group by year and other appropriate variableplotdat = pd.DataFrame({"Open": [], "High": [], "Low": [], "Close": []}) # Create empty data frame containing what will be plottedfor name, group in grouped:plotdat = plotdat.append(pd.DataFrame({"Open": group.iloc[0,0],"High": max(group.High),"Low": min(group.Low),"Close": group.iloc[-1,3]},index = [group.index[0]]))if stick == "week": stick = 5elif stick == "month": stick = 30elif stick == "year": stick = 365elif (type(stick) == int and stick >= 1):transdat["stick"] = [np.floor(i / stick) for i in range(len(transdat.index))]grouped = transdat.groupby("stick")plotdat = pd.DataFrame({"Open": [], "High": [], "Low": [], "Close": []}) # Create empty data frame containing what will be plottedfor name, group in grouped:plotdat = plotdat.append(pd.DataFrame({"Open": group.iloc[0,0],"High": max(group.High),"Low": min(group.Low),"Close": group.iloc[-1,3]},index = [group.index[0]]))else:raise ValueError('Valid inputs to argument "stick" include the strings "day", "week", "month", "year", or a positive integer')# Set plot parameters, including the axis object ax used for plottingfig, ax = plt.subplots()fig.subplots_adjust(bottom=0.2)if plotdat.index[-1] - plotdat.index[0] < pd.Timedelta('730 days'):weekFormatter = DateFormatter('%b %d')  # e.g., Jan 12ax.xaxis.set_major_locator(mondays)ax.xaxis.set_minor_locator(alldays)else:weekFormatter = DateFormatter('%b %d, %Y')ax.xaxis.set_major_formatter(weekFormatter)ax.grid(True)# Create the candelstick chartcandlestick_ohlc(ax, list(zip(list(date2num(plotdat.index.tolist())), plotdat["Open"].tolist(), plotdat["High"].tolist(),plotdat["Low"].tolist(), plotdat["Close"].tolist())),colorup = "black", colordown = "red", width = stick * .4)# Plot other series (such as moving averages) as linesif otherseries != None:if type(otherseries) != list:otherseries = [otherseries]dat.loc[:,otherseries].plot(ax = ax, lw = 1.3, grid = True)ax.xaxis_date()ax.autoscale_view()plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')plt.show()pandas_candlestick_ohlc(apple)

烛状图中黑色线条代表该交易日闭市价格高于开市价格(盈利),红色线条代表该交易日开市价格高于闭市价格(亏损)。刻度线代表当天交易的最高价和最低价(影线用来指明烛身的哪端是开市,哪端是闭市)。烛状图在金融和技术分析中被广泛使用在交易决策上,利用烛身的形状,颜色和位置。

第四步、把多个公司股票绘制在一张图上

当然,烛柱图不能绘制多个股票,需要绘制线段图在一个图上。

获取microsoft公司股价:

import pandas_datareader.data as web
import datetime
import fix_yahoo_finance as yf
yf.pdr_override()start=datetime.datetime(2017, 1, 1)
end=datetime.datetime.today()
microsoft=web.get_data_yahoo('MSFT',start,end)
microsoft
Out[1]: Open       High        Low      Close  Adj Close    Volume
Date
2017-01-03  62.790001  62.840000  62.130001  62.580002  60.431488  20694100
2017-01-04  62.480000  62.750000  62.119999  62.299999  60.161095  21340000
2017-01-05  62.189999  62.660000  62.029999  62.299999  60.161095  24876000
2017-01-06  62.299999  63.150002  62.040001  62.840000  60.682560  19922900
2017-01-09  62.759998  63.080002  62.540001  62.639999  60.489429  20256600

获取google公司股价:

import pandas_datareader.data as web
import datetime
import fix_yahoo_finance as yf
yf.pdr_override()start=datetime.datetime(2017, 1, 1)
end=datetime.datetime.today()
google=web.get_data_yahoo('GOOG',start,end)
google.head()Open        High         Low       Close   Adj Close  \
Date
2017-01-03  778.809998  789.630005  775.799988  786.140015  786.140015
2017-01-04  788.359985  791.340027  783.159973  786.900024  786.900024
2017-01-05  786.080017  794.479980  785.020020  794.020020  794.020020
2017-01-06  795.260010  807.900024  792.203979  806.150024  806.150024
2017-01-09  806.400024  809.966003  802.830017  806.650024  806.650024   Volume
Date
2017-01-03  1657300
2017-01-04  1073000
2017-01-05  1335200
2017-01-06  1640200
2017-01-09  1272400  

把apple、Microsoft和Google三家股价的从2017年1月1日到现在的Adj Close值合在一起

import pandas_datareader.data as web
import datetime
import fix_yahoo_finance as yf
yf.pdr_override()start=datetime.datetime(2017, 1, 1)
end=datetime.datetime.today()apple=web.get_data_yahoo('AAPL',start,end)
microsoft=web.get_data_yahoo('MSFT',start,end)
google=web.get_data_yahoo('GOOG',start,end)import pandas as pd
stocks = pd.DataFrame({"AAPL": apple["Adj Close"],"MSFT": microsoft["Adj Close"],"GOOG": google["Adj Close"]})
stocks     # adj close就是等于adjusted closeOut[8]: AAPL         GOOG        MSFT
Date
2017-01-03  113.013916   786.140015   60.431488
2017-01-04  112.887413   786.900024   60.161095
2017-01-05  113.461502   794.020020   60.161095
2017-01-06  114.726402   806.150024   60.682560
2017-01-09  115.777237   806.650024   60.489429

绘图:

stocks.plot(grid = True)

这张图表的问题在哪里呢?虽然价格的绝对值很重要(昂贵的股票很难购得,这不仅会影响它们的波动性,也会影响你交易它们的难易度),但是在交易中,我们更关注每支股票价格的变化而不是它的价格。Google的股票价格比苹果微软的都高,这个差别让苹果和微软的股票显得波动性很低,而事实并不是那样。

一个解决办法就是用两个不同的标度来作图。一个标度用于苹果和微软的数据;另一个标度用来表示Google的数据。

stocks.plot(secondary_y = ["AAPL", "MSFT"], grid = True)

一个“更好”的解决方法是可视化我们实际关心的信息:股票的收益。这需要我们进行必要的数据转化。数据转化的方法很多。其中一个转化方法是将每个交易日的股票交个跟比较我们所关心的时间段开始的股票价格相比较。也就是:

这需要转化stock对象中的数据,操作如下:

# df.apply(arg) will apply the function arg to each column in df, and return a DataFrame with the result
# Recall that lambda x is an anonymous function accepting parameter x; in this case, x will be a pandas Series object
stock_return = stocks.apply(lambda x: x / x[0])
stock_return.head()Out[11]: AAPL      GOOG      MSFT
Date
2017-01-03  1.000000  1.000000  1.000000
2017-01-04  0.998881  1.000967  0.995526
2017-01-05  1.003960  1.010024  0.995526
2017-01-06  1.015153  1.025453  1.004155
2017-01-09  1.024451  1.026090  1.000959
stock_return.plot(grid = True).axhline(y = 1, color = "black", lw = 2)

这个图就有用多了。现在我们可以看到从我们所关心的日期算起,每支股票的收益有多高。而且我们可以看到这些股票之间的相关性很高。它们基本上朝同一个方向移动,在其他类型的图表中很难观察到这一现象。

我们还可以用每天的股值变化作图。一个可行的方法是我们使用后一天$t + 1$和当天$t$的股值变化占当天股价的比例:

我们也可以比较当天跟前一天的价格:

以上的公式并不相同,可能会让我们得到不同的结论,但是我们可以使用对数差异来表示股票价格变化:

(这里的是自然对数,我们的定义不完全取决于使用还是.) 使用对数差异的好处是该差异值可以被解释为股票的百分比差异,但是不受分母的影响。

下面的代码演示了如何计算和可视化股票的对数差异:

# Let's use NumPy's log function, though math's log function would work just as well
import numpy as np
stock_change = stocks.apply(lambda x: np.log(x) - np.log(x.shift(1))) # shift moves dates back by 1.
stock_change.head()
Out[14]: AAPL      GOOG      MSFT
Date
2017-01-03       NaN       NaN       NaN
2017-01-04 -0.001120  0.000966 -0.004484
2017-01-05  0.005073  0.009007  0.000000
2017-01-06  0.011087  0.015161  0.008630
2017-01-09  0.009118  0.000620 -0.003188
stock_change.plot(grid = True).axhline(y = 0, color = "black", lw = 2)

你更倾向于哪种转换方法呢?从相对时间段开始日的收益差距可以明显看出不同证券的总体走势。不同交易日之间的差距被用于更多预测股市行情的方法中,它们是不容被忽视的。

移动平均值

图表非常有用。在现实生活中,有些交易人在做决策的时候几乎完全基于图表(这些人是“技术人员”,从图表中找到规律并制定交易策略被称作技术分析,它是交易的基本教义之一。)下面让我们来看看如何找到股票价格的变化趋势。

一个q天的移动平均值(用来表示)定义为:对于某一个时间点t,它之前q天的平均值。

移动平均值可以让一个系列的数据变得更平滑,有助于我们找到趋势。q值越大,移动平均对短期的波动越不敏感。移动平均的基本目的就是从噪音中识别趋势。快速的移动平均有偏小的q,它们更接近股票价格;而慢速的移动平均有较大的q值,这使得它们对波动不敏感从而更加稳定。

pandas提供了计算移动平均的函数。下面我将演示使用这个函数来计算苹果公司股票价格的20天(一个月)移动平均值,并将它跟股票价格画在一起。

import pandas as pd  # 不加这个,会提示NameError: name 'pd' is not defined
pandas_candlestick_ohlc(apple)
apple["20d"] = np.round(apple["Close"].rolling(window = 20, center = False).mean(), 2)
pandas_candlestick_ohlc(apple.loc['2017-01-01':'2017-08-07',:], otherseries = "20d")

注意到平均值的起始点时间是很迟的。我们必须等到20天之后才能开始计算该值。这个问题对于更长时间段的移动平均来说是个更加严重的问题。因为我希望我可以计算200天的移动平均,我将扩展我们所得到的苹果公司股票的数据,但我们主要还是只关注2016。

import pandas_datareader.data as web
import datetime
import fix_yahoo_finance as yf
yf.pdr_override()start = datetime.datetime(2010,1,1)
apple=web.get_data_yahoo('AAPL',start,end)
apple["20d"] = np.round(apple["Close"].rolling(window = 20, center = False).mean(), 2)pandas_candlestick_ohlc(apple.loc['2016-01-04':'2016-08-07',:], otherseries = "20d")

你会发现移动平均比真实的股票价格数据平滑很多。而且这个指数是非常难改变的:一支股票的价格需要变到平局值之上或之下才能改变移动平均线的方向。因此平均线的交叉点代表了潜在的趋势变化,需要加以注意。

交易者往往对不同的移动平均感兴趣,例如20天,50天和200天。要同时生成多条移动平均线也不难:

apple["50d"] = np.round(apple["Close"].rolling(window = 50, center = False).mean(), 2)
apple["200d"] = np.round(apple["Close"].rolling(window = 200, center = False).mean(), 2)pandas_candlestick_ohlc(apple.loc['2016-01-04':'2016-08-07',:], otherseries = ["20d", "50d", "200d"])

20天的移动平均线对小的变化非常敏感,而200天的移动平均线波动最小。这里的200天平均线显示出来总体的熊市趋势:股值总体来说一直在下降。

实例操作:Python提取雅虎财经数据,并做数据分析和可视化相关推荐

  1. Python采集双色球数据,做数据分析,让我自己实现自己的富豪梦

    来唠点嗑? 咳咳,最近是咋的了,某站掀起了一股双色球热潮?一般我自己的账号上,是很少看到关于python这些内容的,都是小姐姐和热梗,或者其他搞笑视频 由于

  2. 基于Python的海量豆瓣电影、数据获取、数据预处理、数据分析、可视化、大屏设计项目(含数据库)

    目录 项目介绍 研究背景 国内外研究现状分析 研究目的 研究意义 研究总体设计 网络爬虫介绍 豆瓣电影数据的采集 数据预处理 大数据分析及可视化 豆瓣影评结构化分析 大屏可视化 文本可视化 总结 每文 ...

  3. [知识图谱实战篇] 三.Python提取JSON数据、HTML+D3构建基本可视化布局

    前面作者讲解了很多知识图谱原理知识,包括知识图谱相关技术.Neo4j绘制关系图谱等,但仍缺少一个系统全面的实例.为了加深自己对知识图谱构建的认识,为后续创建贵州旅游知识图谱打下基础,作者深入学习了张宏 ...

  4. 怎么在python提取别的数据了_别再问如何用python提取PDF内容了!

    作者:陈熹 来源:早起Python 大家好,在之前的办公自动化系列文章中我们已经详细介绍了如何使用python批量处理PDF文件,包括合并.拆分.水印.加密等操作. 今天我们再次回到PDF,详细讲解如 ...

  5. python提取表格数据匹配_excle表格处理python|python怎么提取excle表格数据

    python怎么提取excle表格数据 通过实例来,在Excle表格中有数据和文字结合的内容 把Excle表格中的,复制--粘贴到word中. 按下ctrl F键,打开"查找和替换" ...

  6. python分析数据走势_Python数据分析及可视化实例之个股走势预测(26)

    1.项目背景: 仅仅用来练手,个股走势如果真预测准确了,都就改行当操盘手了,哈哈! 但话又说回来,如果把数据曲线特征提取出来,再进行对比异常判断,也是可以的. 数据源,请关注微信公众号:海豹战队,回复 ...

  7. python后端还是数据分析好_数据分析和web后端选哪个 知乎

    数据分析和web后端选哪个 知乎以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 数据分析和web后端选哪个 知乎 WEB ...

  8. 手把手带你用Python做数据分析和可视化项目实战,能写进简历的那种!(另送15个实战案例)...

    最近几年,数据分析可真是太火了. 阿里.字节等互联网巨头基于大数据打造的商业模式获得巨大成功,使得"数据思维"."数据能力"迅速成为衡量职场人能力的核心指标,专 ...

  9. python信用卡违约预测分析_Python数据分析及可视化实例之银行信用卡违约预测(24)...

    1.项目背景: 银行体系对于信用可违约进行预测,原始数据集如下: 2.分析步骤: (1)数据清洗(Data Cleaning) (2) 探索性可视化(Exploratory Visualization ...

最新文章

  1. 九种浏览器端缓存机制知多少(转)
  2. 4.元组tuple:戴上了枷锁的列表
  3. c语言 艺术编程,C语言编程艺术--条件编译(原创)
  4. 获得TADIR-OBJECT全部的entry list
  5. 拼多多开卖飞天茅台酒,比市价低1000元,茅台也表示没有合作?
  6. leetcode:Single Number【Python版】
  7. 更好的设计你的 REST API
  8. linux 下 sudo 指令不需要输入密码的配置
  9. JSP内置对象实例实训报告
  10. 视频修复工具修复损坏avi视频文件
  11. 最新最全的阿里云产品手册出炉
  12. 英语语法快速入门1--简单句(附思维导图)
  13. 树莓派简单入门(基本小案例)
  14. 基于WEB的网上在线图书商城
  15. VMware® Workstation 16 Pro创建WIN7虚拟机教程
  16. java 读取 doc_java如何读取doc文件
  17. LintCode 661. 把二叉搜索树转化成更大的树
  18. Innovation - Face++ - 当人脸识别遇上互联网
  19. mysql正则匹配大写字母_正则表达式,大写字母,怎么匹配?
  20. 如何简单的修改文件名及文件扩展名重命名

热门文章

  1. 聊聊AppDelegate解耦
  2. 高德地图实现多点标注marker和动态信息窗体
  3. 数据库系统的组成与结构
  4. Structured Streaming 编程模型
  5. 吃货们看好了!python+selenium爬取淘宝美食
  6. 奥丁软件管家解压密码汇总_管家婆财贸ERP如何做销售分析?
  7. 广州的11个辖区_对不起,你真的不了解广州11个区!
  8. Mysql,如果几分钟不用,再次操作时就会很慢
  9. 红叶最多情,一舞寄相思
  10. 攻击法国海军病毒Conficker在中国网络同步蔓延