Pythonで日経平均株価のグラフを作成してみた(前編)

shimo
VELTRA Engineering
Published in
8 min readMar 12, 2020

前編では、APIで日経平均株価のデータの取得と前処理、移動平均線の表示まで行います。
後編では、前編のデータを使い、ポイントアンドフィギュア(以下: P&F)の表示を行います。

PythonはJupyter Notebookで実行しています。

はじめに:

Pythonを使ってAPIでデータ取得、前処理、グラフ表示をするのが目的です。要件をみたすデータとして、日経平均株価を使って移動平均線とP&Fを表示しています。

こちらのデータを使って投資を薦めているわけではありません。

日経平均株価のデータ取得:

日経平均株価はQuandl APIから取得しています。

制限はありますが、フリーで使用できます。データ取得にはユーザー登録後、APIキーを発行します。

今回は”Nikkei/USD”を使用します。

ドキュメントにしたがってエンドポイントを作成します。

データはjsonで取得するので、下記の用になります。

https://www.quandl.com/api/v3/datasets/CHRIS/CME_NK2/data.json?api_key={API_TOKEN}

では実際に日経平均株価を取得してみます

まず、必要なライブラリをimportします
データの前処理、グラフ表示に必要なライブラリもimportしています。

# API
import requests
import json
import datetime as dt
# 必要なデータを絞るための日付系
from dateutil.relativedelta import relativedelta
from pytz import timezone
# データ前処理、グラフ表示
import numpy as np
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt

APIをコールしてデータ取得

# API key
API_TOKEN = ‘your API key’
# エンドポイントを定義
url = ‘https://www.quandl.com/api/v3/datasets/CHRIS/CME_NK2/data.json?api_key={API_TOKEN}'
# json でデータ取得
catched_response = requests.get(url)
json_data = catched_response.json()

Quandl Python Packageも配布されていますが、今回はrequestsモジュールを使います。

取得したデータを確認。欲しいデータは”dataset_data”内にある”column_names”と”data”になります。

DataFrame型にデータをセットします。

# jsonから必要なデータを取得
columns = json_data[‘dataset_data’][‘column_names’]
values = json_data[‘dataset_data’][‘data’]
# DataFrameにセット後日付カラムをindexに設定
df = pd.DataFrame(values, columns=columns)
df.loc[:,'Date'] = pd.to_datetime(df.loc[:, 'Date'])
df.set_index(‘Date’, inplace=True)

DataFrameにセットしたデータを確認します。

df.info()

データタイプと個数が確認できます。

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 7406 entries, 2020-02-12 to 1990-09-26
Data columns (total 8 columns):
Open 7197 non-null float64
High 7379 non-null float64
Low 7349 non-null float64
Last 7404 non-null float64
Change 0 non-null object
Settle 7406 non-null float64
Volume 7406 non-null float64
Previous Day Open Interest 7406 non-null float64
dtypes: float64(7), object(1)
memory usage: 520.7+ KB

総数 7406に対して、Open, High, Low, Lastの数がバラバラですので、欠損値が存在しているようです。

今回は終値だけ欲しいのでデータの確認、欠損値の処理は”Last”のみ行います

欠損値があるか確認します。

df[df.loc[:, ‘Last’].isnull()]

確かに2件データがとれます。

欠損値を処理します。

欠損値は以下のルールで処理します。

高値: 欠損値前後のNaNではない高値に線形で伸びるとする。

終値: 欠損値前後のNaNではない終値に線形で伸びるとする。ただし高値以上にならない

欲しいデータは終値だけなのですが、高値とも比較したいので、欠損値の処理は高値も行うことにします。

その為、高値、終値の順番に欠損値の処理を行います。

df.loc[:,’High’].interpolate(inplace=True)
df.loc[:,’Last’] = np.minimum(df.loc[:,’Last’].interpolate(), df.loc[:,’High’])

np.minimumで終値と高値を比較し低い方を取得しています。

interpolateで前後のNaN以外の値を取得し、その間の値を取得しています。高値は該当するオブジェクトをそのまま変更したいので、”inplace=True”を指定しています。

欠損値が埋まったことを確認します。

df.info()

総数 とLastが同じ値になっているので、欠損値が埋まったことが確認できます。

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 7406 entries, 2020-02-12 to 1990-09-26
Data columns (total 8 columns):
Open 7197 non-null float64
High 7406 non-null float64
Low 7349 non-null float64
Last 7406 non-null float64
Change 0 non-null object
Settle 7406 non-null float64
Volume 7406 non-null float64
Previous Day Open Interest 7406 non-null float64
dtypes: float64(7), object(1)
memory usage: 840.7+ KB

データ取得から欠損値の処理までのデータの前処理が終わりました。

日経平均株価の移動平均線を表示:

移動平均線のグラフを表示しています。

全期間だとデータ量が多く見にくいので、1年分のみ表示します。

# 1年前の日付を取得
today = dt.datetime.now(timezone('Asia/Tokyo'))
t_year = today - relativedelta(years=1)
t_date = t_year.strftime('%Y-%m')
# 1年分の終値を取得し、グラフ表示
df_target = df.loc[:t_date,’Last’].sort_index()
df_target.plot()
# 移動平均線も表示
df_target.rolling(window = 5).mean().plot()
df_target.rolling(window = 25).mean().plot()

終値の移動平均線を表示したいので、終値だけを取得し、index(日付)でソートします。

日経平均株価と、5日移動平均線、25日移動平均線を表示します。

移動平均線の表示ができました。

前編では主に、PandasのDataframeを使ったデータ処理がメインでした。後編のP&Fの表示では、matplotlibをメインに使っています。

参考にしたURL:

Jupyter Notebook: https://ai-inter1.com/jupyter-notebook/

pandas: https://pandas.pydata.org/pandas-docs/stable/reference/index.html

matplotlib: https://matplotlib.org/users/index.html

移動平均線: https://fx-quicknavi.com/chart/moving-average/

P&F: https://fx-quicknavi.com/chart/point-and-figure/

Quandl API: https://www.quandl.com/

--

--