ストックドッグ

KatoTakahiro。金融系の会社で働くSEが株やPython、その他諸々について書いています。サービスも運営してます→http://fmbrain.work

S◯I証券風のチャートをmatplotlibで作ってみた 〜Python〜

f:id:doz13189:20160818090415p:plain

S◯I証券風のチャートをmatplotlibで作ってみました。
サイバネット(4312)の約半年間分のチャートをプロットしています。
sma=移動平均線で、5日、25日、60日、100日、300日を表示しています。


f:id:doz13189:20160822031206p:plain

出来高のグラフも合わせて、作りました。
調整後終値と一緒にプロットしているので比べやすいと思います。

無料で使えて、かつ自分が表示したい機能をすべて持っているチャートはなかなか無いので、自分で作ってみました。

簡単ではありますが、コードの解説もしているのでもしよければご覧ください。

doz13189.hatenablog.com

doz13189.hatenablog.com

doz13189.hatenablog.com


以下がソースコードです。ごちゃごちゃしているので、時間があれば整理をします。

import pandas
import datetime
import matplotlib.pyplot as plt

def scraping_yahoo(code, start, end, term):
	base = "http://info.finance.yahoo.co.jp/history/?code={0}.T&{1}&{2}&tm={3}&p={4}"

	start = str(start)
	start = start.split("-")
	start = "sy={0}&sm={1}&sd={2}".format(start[0], start[1], start[2])
	end = str(end)
	end = end.split("-")
	end = "ey={0}&em={1}&ed={2}".format(end[0], end[1], end[2])
	page = 1

	result = []
	while True:
		url = base.format(code, start, end, term, page)
		df = pandas.read_html(url, header=0)
		if len(df[1]) == 0:
			break

		result.append(df[1])
		page += 1
	result = pandas.concat(result)
	result.columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close']

	return result


def generate(data):
	data_frame = data[["Date","Open","Close","High","Low",'Adj Close',"Volume",]]

	hiduke = pandas.DataFrame(data_frame["Date"])
	hiduke.columns = ["Hiduke"]

	dates = []
	for day in data_frame["Date"]:
		day = day.replace("年", "-")
		day = day.replace("月", "-")
		day = day.replace("日", "")
		time = datetime.datetime.strptime(day, '%Y-%m-%d')
		dates.append(time)

	data_frame["Date"] = dates
	tmp = data_frame["Date"].values.astype("datetime64[D]")
	d = tmp
	
	data_frame["Date"] = tmp.astype(float)

	index = len(data_frame["Date"])
	index_data = []
	for x in range(index):
		index_data.append(x)

	data_frame.index = index_data
	hiduke.index = index_data
	
	data_frame = pandas.concat([data_frame, hiduke], axis=1)

	return data_frame


class Score:
	def __init__(self, data, code):
		self.data = data
		self.code = code


	def sma_addition(self):

		sma5 = pandas.Series.rolling(self.data['Adj Close'], window=5,center=False).mean()
		sma5 = pandas.DataFrame(sma5)
		sma5.columns = ["sma5"]
		sma5 = sma5.dropna(subset=["sma5"])
		kago = [go for go in range(len(sma5))]
		sma5.index = kago
		new_data = pandas.concat([self.data, sma5], axis=1)

		
		sma25 = pandas.Series.rolling(self.data['Adj Close'], window=25,center=False).mean()
		sma25 = pandas.DataFrame(sma25)
		sma25.columns = ["sma25"]
		sma25 = sma25.dropna(subset=["sma25"])
		kago = [go for go in range(len(sma25))]
		sma25.index = kago
		new_data = pandas.concat([new_data, sma25], axis=1)

		sma60 = pandas.Series.rolling(self.data['Adj Close'], window=60,center=False).mean()
		sma60 = pandas.DataFrame(sma60)
		sma60.columns = ["sma60"]
		sma60 = sma60.dropna(subset=["sma60"])
		kago = [go for go in range(len(sma60))]
		sma60.index = kago
		new_data = pandas.concat([new_data, sma60], axis=1)

		sma100 = pandas.Series.rolling(self.data['Adj Close'], window=100,center=False).mean()
		sma100 = pandas.DataFrame(sma100)
		sma100.columns = ["sma100"]
		sma100 = sma100.dropna(subset=["sma100"])
		kago = [go for go in range(len(sma100))]
		sma100.index = kago
		new_data = pandas.concat([new_data, sma100], axis=1)

		sma300 = pandas.Series.rolling(self.data['Adj Close'], window=300,center=False).mean()
		sma300 = pandas.DataFrame(sma300)
		sma300.columns = ["sma300"]
		sma300 = sma300.dropna(subset=["sma300"])
		kago = [go for go in range(len(sma300))]
		sma300.index = kago
		new_data = pandas.concat([new_data, sma300], axis=1)

		choice_data = new_data.ix[:, ["Date","Open","Close","High","Low",'Adj Close',"Volume","Hiduke","sma5","sma25","sma60","sma100","sma300"]]
		self.choice_data = choice_data

		return self.choice_data



	def ochl(self):
		from matplotlib.finance import candlestick_ochl
		ax1 = plt.subplot()
		try:
			candlestick_ochl(ax1, self.choice_data.values, width=0.7, colorup='#ff1e1e', colordown='#1eff1e')
		except TypeError:
			pass


		plt.plot(self.choice_data["Date"], self.choice_data["sma5"], color="#1e8eff", label = "sma5")
		plt.plot(self.choice_data["Date"], self.choice_data["sma25"], color="#ff8e1e", label = "sma25")
		plt.plot(self.choice_data["Date"], self.choice_data["sma60"], color="#ff1e8e", label = "sma60")
		plt.plot(self.choice_data["Date"], self.choice_data["sma100"], color="#1effff", label = "sma100")
		plt.plot(self.choice_data["Date"], self.choice_data["sma300"], color="#ff7fbf", label = "sma300")
		plt.legend(loc='best')

		plt.xticks(self.choice_data["Date"][::40], self.choice_data["Hiduke"][::40])
		plt.grid(color='#f5f5f5')

		ax1.patch.set_facecolor('#333333')

		try:
			x_left = self.choice_data["Date"][120]
		except KeyError:
			left = len(self.choice_data["Date"])
			x_left = left - 1
		x_right = self.choice_data["Date"][0]
		plt.xlim(x_left - 5, x_right + 5)

		filename_candle_day = self.code + "_candle_day.svg"
		plt.savefig(filename_candle_day)

		return plt.clf()


	def values(self):
		ax1 = plt.subplot()
		ax1.bar(self.data["Date"], self.data["Volume"],  color='#1e8eff', edgecolor="#333333")
		ax2 = ax1.twinx()

		ax1.patch.set_facecolor('#333333')
		plt.grid(color='#f5f5f5')
		try:
			x_left = self.choice_data["Date"][120]
		except KeyError:
			left = len(self.choice_data["Date"])
			x_left = left - 1
		x_right = self.choice_data["Date"][0]
		plt.xlim(x_left - 5, x_right + 5)
		ax2.plot(self.data["Date"], self.data["Adj Close"], color="#ff1e8e")

		filename_values_day = self.code + "_values_day.svg"
		plt.savefig(filename_values_day)

		return plt.clf()






if __name__ == "__main__":
	company = 4312

	EndDate = datetime.date.today()
	StartDate = EndDate - datetime.timedelta(days=60)#640

	data = scraping_yahoo(company, StartDate, EndDate, "d")
	generate_data = generate(data)
	big_company = Score(generate_data, str(company))
	big_company.sma_addition()
	big_company.ochl()
	big_company.values()