from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, MONDAY,date2num
from mpl_finance import candlestick_ohlc #matplotlib版本不同包可能不一样
import matplotlib.pyplot as plt
def pandas_candlestick_ohlc(data, stick = "day", otherseries = None):
"""
:param data: 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 lines
This 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 mondays
alldays = DayLocator() # minor ticks on the days
dayFormatter = DateFormatter('%d') # e.g., 12
# Create a new DataFrame which includes OHLC data for each period specified by stick input
transdat = data.loc[:,["Open", "High", "Low", "Close"]]
if (type(stick) == str):
if stick == "day":
plotdat = transdat
stick = 1 # Used for plotting
elif stick in ["week", "month", "year"]:
if stick == "week":
transdat["week"] = pd.to_datetime(transdat.index).map(lambda x: x.isocalendar()[1]) # Identify weeks
elif stick == "month":
transdat["month"] = pd.to_datetime(transdat.index).map(lambda x: x.month) # Identify months
transdat["year"] = pd.to_datetime(transdat.index).map(lambda x: x.isocalendar()[0]) # Identify years
grouped = transdat.groupby(list(set(["year",stick]))) # Group by year and other appropriate variable
plotdat = pd.DataFrame({"Open": [], "High": [], "Low": [], "Close": []}) # Create empty data frame containing what will be plotted
for 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 = 5
elif stick == "month": stick = 30
elif stick == "year": stick = 365
elif (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 plotted
for 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 plotting
fig, 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 12
ax.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 chart
candlestick_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 lines
if otherseries != None:
if type(otherseries) != list:
otherseries = [otherseries]
data.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()
百度为例
以百度2015-1-1至当前日期的股票数据为例绘图
import pandas as pd
start = dt.datetime(2015,1,1)#时间2010-1-1
end = dt.datetime.today()
baidu = web.DataReader('BIDU', 'yahoo',start,end)
pandas_candlestick_ohlc(baidu)
baidu["20d"] = np.round(baidu["Close"].rolling(window = 20, center = False).mean(), 2)
pandas_candlestick_ohlc(baidu.loc['2019-01-01':'2019-04-22',:], otherseries = "20d")
import pandas_datareader as web
import datetime as dt
import os
import pickle
def get_data_from_yahoo(reload_sp500 = False):
if reload_sp500:
tickers = save_sp500_tickers()
else:
with open("sp500tickers45482.pickle","rb") as f:
tickers = pickle.load(f)
if not os.path.exists('stock_dfs45482'):
os.makedirs('stock_dfs45482')
start = dt.datetime(2010,1,1)
end = dt.datetime.today()
num = 0
for ticker in tickers:
num += 1
if('.B'not in ticker):#####################
if not os.path.exists('stock_dfs45482/{}.csv'.format(ticker)):
df = web.DataReader(ticker, 'yahoo', start, end)
df.to_csv('stock_dfs45482/{}.csv'.format(ticker))
print("正在下载{0:>5}...{1} / 500".format(ticker,num))
else:
print("文件{0:>5}已经存在. {1}/500".format(ticker,num))
else: #############################
print("error sample:"+ticker)