记下自己的研究成果是件开心的事情,本文介绍用Python3将股票历史行情画成K线图,以及添加5日,10日,N日均线。
首先,是获取数据源,一般分两种,一是直接从财经类网站读取;二是读取本地数据文件。我是先从财经网站下载历史行情数据csv文件,然后放到工程文件夹里。
####从雅虎财经获取历史行情####
from matplotlib.finance import quotes_historical_yahoo_ohlc
start = (2017, 1, 1)
end = (2017, 7, 12)
stock = quotes_historical_yahoo_ohlc("399300.ss", start, end)
if len(stock) == 0:
raise SystemExit
##从雅虎获取google的股价数据###
import datetime
import pandas_datareader.data as web
start = datetime.datetime(2016, 10, 1)
end = datetime.date.today()
goog = web.DataReader("GOOG", "yahoo", start, end)
方式二,读取本地数据文件
import pandas as pd
stock = pd.read_csv("hs300_399300.csv")
csv文件如下:
然后,进行数据预处理,或者说数据清洗。
#import sys
# 显示编译器默认编码格式
print(sys.getdefaultencoding)
# 读取前28行数据,将第一列解析为时间格式,将第一列指定为索引,文件编码方式为ANSI
stock = pd.read_csv("hs300_399300.csv",nrows=28, parse_dates=[0], index_col=0, encoding="ANSI")
# 逆序排序
stock = stock[::-1]
print(stock.info())
print(stock.head())
print(stock.columns)
可以看到数据信息,总共28行,时间索引为2017-05-26到2017-07-06,没有空值,以及各列的数据类型。若数据有缺损或者有多余空格,就要进行调整。
数据没问题后就可以开始画图的了,首先用自带的plot()画单列数据的图:
# 网格开启True
stock["收盘价"].plot(grid=True)
stock["最高价"].plot()
可以看到它的横坐标竟然是以时间为刻度从2017-05-28到2017-07-02,原因是我们之前将csv文件第一列解析成时间格式,并且设为索引。如果没这么做,那么横坐标将为0,1,2,3....28.这一点在后面将不同坐标系的图绘入同一坐标系中非常重要。
K线图又称蜡烛图,起源于日本德川幕府时代,当时的商人用此图来记录米市的行情和价格波动,后来K线图被引入到股票市场。每天的四项指标数据用如下蜡烛形状的图形来记录,不同的颜色代表涨跌情况。
基本背景知识介绍完,上主菜:
import matplotlib.pyplot as plt
from matlplotlib.dates import DateFormatter,WeekdayLocator, DayLocator, MONDAY
import pandas as pd
import matplotlib.dates as mdates
from matplotlib.finance import candlestick_ohlc,quotes_historical_yahoo_ohlc
import numpy as np
def candle(stock, stocks, others=None):
# 将时间数据转换为pandas的时间格式
stock['日期'] = pd.to_datetime(stock['日期'])
# 将时间数据转换为matplotlib的时间格式
stock['日期'] = stock['日期'].apply(lambdad: mdates.date2num(d.to_pydatetime()))
# 将需要数据转换为元组
tuples = [tuple(x)for x in stock[['日期', '开盘价', '最高价', '最低价', '收盘价']]]
# 获得fig和ax对象
fig, ax =plt.subplots()
# 调节横坐标距离底部的高度
fig.subplots_adjust(bottom=0.2)
# 设置横坐标主刻度标签位置,标签文本格式(显示每周周一),年月日
mondays =WeekdayLocator(MONDAY)
ax.xaxis.set_major_locator(mondays)
mondays_formatter = DateFormatter("%Y-%m-%d")
ax.xaxis.set_major_formatter(mondays_formatter)
# 设置横坐标次刻度标签位置
days =DayLocator()
ax.xaxis.set_minor_locator(days)
# day_formatter= DateFormatter("%d")
# ax.xaxis.set_minor_formatter(day_formatter)
# 网格,x坐标轴网格使用主刻度,y坐标轴使用副刻度
#ax.xaxis.grid(True, which='major')
#ax.yaxis.grid(True, which='minor')
ax.grid(True)
# 绘图
candlestick_ohlc(ax,tuples, width=0.6, colorup='r', colordown='g')
# 其它折线
if others isnot None:
for each inothers:
plt.plot(stocks[each], label=each)
plt.legend()
ax.xaxis_date()
ax.autoscale_view()
# 设置横坐标标签的样式,获得当前坐标轴plt.gca,获得x轴刻度标签get_xticklabels(),转换角度,倾斜角度
plt.setp(plt.gca().get_xticklabels(), rotation=45,horizontalalignment='right')
plt.title("hs300_399300")
#plt.xlabel("time")
#plt.ylabel('price')
plt.show()
5日均线:5天的收盘价的平均值
10日均线:10天的收盘价的平均值
依次类推。
给数据文件加一列“5日均线”,和‘10日均线’
stocks["5days"] = np.round(stocks["收盘价"].rolling(window=5, center=False).mean(), 2)
stocks["10days"] = np.round(stocks["收盘价"].rolling(window=10, center=False).mean(), 2)
现在打印下前60行
可见现在5,10日均线的数据都以计算并添加进数据文件中,接下来就是将其绘制入K线图上
# 读取数据画k线图
stock = pd.read_csv("hs300_399300", nrows=60,encoding="ANSI")
stock = stock[::-1]
# 读取数据画均线图
stock = pd.read_csv("hs300_399300", nrows=60,parse_dates=[0], index_col=0, encoding="ANSI")
stock = stock[::-1]
# 重命名columns索引,有些编码方式不支持中文,可以换成英文
stock.index.rename('日期', inplace=True)
stock.rename(columns={}, inplace=True)
candle(stock, stocks, ["5days","10days"])
运行输出: