Yahoo! Financeからビットコインの過去の価格データを取り込む
ここでは、Yahoo! Financeからビットコインの過去(2014/1/1から今日まで)の価格データをダウンロードします。
VS Codeから新規ファイル「*.py」を作成したら行1-144をコピペします。
Pythonのソースコードには「#%%」を埋め込んで「Jupter Notebook」のようにセル単位で実行します。
VS Codeでは「#%%...#%%」の間がセルになります。
行9-36ではPythonの各種ライブラリを取り込んでいます。
行37ではPythonの警告メッセージを抑止しています。
行39ではMatplotlibのデフォルトのスタイルを設定しています。
行45-76ではユーザー定義関数「load_data()」を定義しています。
この関数ではYahoo! Financeから株価、仮想通貨などの価格データをダウンロードしてPandasのDataFrameに格納して返します。
この関数の引数1には、株価のティッカーまたは仮想通貨のシンボルを指定します。
ビットコインのデータをダウンロードするときは「BTC-USD」を指定します。
引数2, 3にはダウンロードするデータの範囲を指定します。
引数4, 5には範囲の単位と間隔を指定します。
たとえば、「peridod='1d', interval='1m'」と指定したときは、1分間隔のデータがダウンロードされます。
「peridod='1d', interval='1h'」と指定したときは、1時間間隔のデータがダウンロードされます。
「peridod='1d', interval='1d'」と指定したときは、1日間隔のデータがダウンロードされます。
行79-85ではユーザー定義関数「get_data()」を定義しています。
この関数では、CSVファイルに格納されている株・仮想通貨の価格データをPandasのDataFrameに取り込んで戻り値として返します。
行88-107ではビットコイン(BTC-USD)の価格データを取り込んでいます。
取り込んだ価格データはCSVファイル「data/csv/*.csv」に保存します。
CSVファイルは「dl_crypto(BTC-USD)_1d.csv」のような名称で保存されます。
すでに価格データがCSVファイルに保存されているときは、CSVファイルから価格データを取り込みます。
行117-118ではPandasのDataFrameに不正な値がないかチェックしています。
行132-143ではPandasのDataFrameに格納されている価格「close: 終値」を2種類のグラフ(線グラフ、ラググラフ)に表示します。
* Article.py:
# Bitcoin Price Prediction with Deep Learning LSTM Article.py
#%%
#############################################################
### Part 1 : Load / prepare crypto data
#############################################################
### Import the libraires
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import math
import numpy as np # pip install numpy
import matplotlib.pyplot as plt # pip install matplotlib
import matplotlib.dates as mdates
import pandas as pd # pip install pandas
import datetime as dt
from datetime import timedelta
from time import sleep
import yfinance as yf # pip install yfinance
# pip install tensorflow-cpu
# pip install sklearn
# pip install scikit-learn
from sklearn.preprocessing import MinMaxScaler
from keras import models
from keras.layers import Dense, Dropout, LSTM
from keras.models import Sequential
from keras.models import load_model
from sklearn.metrics import mean_squared_error, mean_absolute_error, explained_variance_score, r2_score
from sklearn.metrics import mean_poisson_deviance, mean_gamma_deviance, accuracy_score
import warnings
warnings.simplefilter('ignore')
plt.style.use('fivethirtyeight')
# %%
######################################################################################################################################
def load_data(symbol: str, start_date: dt.datetime , end_date: dt.datetime, period='1d', interval='1d', prepost=True) -> pd.DataFrame:
# valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
# fetch data by interval (including intraday if period < 60 days)
# valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
try:
end_date = end_date + timedelta(days=1)
start_date_str = dt.datetime.strftime(start_date, "%Y-%m-%d")
end_date_str = dt.datetime.strftime(end_date, "%Y-%m-%d")
print(f"Loading data for {symbol}: start_date={start_date_str}, end_date={end_date_str}, {period=}, {interval=}")
df = yf.download(symbol, start=start_date_str, end=end_date_str, period=period, interval=interval, prepost=prepost)
# Date Open High Low Close Adj Close Volume Symbol : interval=1d,5d,1wk,1mo,3mo
# Datetime Open High Low Close Adj Close Volume Symbol : interval=1m,2m,5m,15m,30m,60m,90m,1h
# Add symbol
df['Symbol'] = symbol
# Reset index
df.reset_index(inplace=True)
# Rename Date or Datetime column name to Time
if interval in '1m,2m,5m,15m,30m,60m,90m,1h':
df.rename(columns={'Datetime': 'Time'}, inplace=True)
else: # interval=1d,5d,1wk,1mo,3mo
df.rename(columns={'Date': 'Time'}, inplace=True)
# Convert column names to lower case
df.columns = df.columns.str.lower()
return df
except:
print('Error loading data for ' + symbol)
return pd.DataFrame()
############################################
def get_data(csv_file: str) -> pd.DataFrame:
print(f"Loading data for {symbol}: {csv_file} ")
df = pd.read_csv(csv_file)
# time,open,high,low,vlose,ddj close,volume,symbol
df['time'] = pd.to_datetime(df['time'])
# df.set_index('time', inplace=True)
return df
### Get the crypto data from Yahoo! Finance
symbol = 'BTC-USD'
interval = '1d'
csv_file = f"data/csv/dl_crypto({symbol})_{interval}.csv" # data/csv/dl_crypto(BTC-USD)_{1d|1m}.csv
isFile = os.path.isfile(csv_file)
if not isFile:
if interval in '1m,2m,5m,15m,30m,60m,90m,1h':
end = dt.datetime.now()
start = end - timedelta(days=7)
else: # interval=1d,5d,1wk,1mo,3mo
start = dt.datetime(2014,1,1)
end = dt.datetime.now()
# load_data(symbol: str, start_date: dt.datetime , end_date: dt.datetime, period='1d', interval={'1m'|'1d'}, prepost=True) -> pd.DataFrame:
df = load_data(symbol, start, end, period='1d', interval=interval)
if df.shape[0] > 0:
df.to_csv(csv_file, index=False)
else:
df = get_data(csv_file)
# end of if not isFile:
# print(df.info())
# print(df.describe())
# print(df)
#%%
### Check null values
print('Null Values:', df.isnull().values.sum())
print('If any NA values:', df.isnull().values.any())
#%%
### Plot Bitcoin price
# df.set_index("time").close.plot(figsize=(16,7), title=f"{symbol} Price")
# plt.show()
#%%
### Plot Line / Lag
plt.figure(figsize=(16,8))
plt.suptitle('Plots', fontsize=22)
plt.subplot(1,2,1)
df.set_index("time").close.plot() # line chart
plt.title('Line Chart')
plt.subplot(1,2,2)
pd.plotting.lag_plot(df['close'], lag=1) # daily lag
plt.title('Daily Lag')
plt.show()
#%%
VS Codeからソースコードの行3-41の任意の行をクリックしてセルを選択します。
セルを選択した状態で[Ctrl + Enter]を同時に押してセルを実行します。
「インタラクティブ」ウィンドウが開いて、IPythonが実行されます。
次に行43-113の任意の行をクリックしてセルを選択したら[Ctrl + Enter]で実行します。
セルが実行されたら「インタラクティブ」ウィンドウの入力エリアに「df.info()」を入力して[Shift + Enter]で実行します。
「df.info()」が実行されてPandasのDataFrameの構造が表示されました。
DataFrameには3054件のデータが格納されています。
DataFrameは「time, close, symbol,...」等の列(カラム)から構成されています。
ここでは「close:終値」のカラムのみ使用します。
同様の手順で「インタラクティブ」ウィンドウから「df.describe()」を入力したら「Shift + Enter」で実行します。
DataFrameのカラム別の各種統計情報が表示されます。
ここでは「close」のカラムの「count, mean, std, min, max」に注目してください。
countにはビットコイン(BTC-USD)のデータ件数(3054)が表示されてます。
min, maxにはビットコインの最安値($178.10)と最高値($ 67,566.82)が表示されています。
最後に「df」を入力したら[Shift + Enter]で実行します。
「インタラクティブ」ウィンドウにはDataFrameの先頭と最後のデータが5件づつ表示されています。
DataFrameにはビットコインの「201/09/17~2023/01/27」のデータが格納されていることが確認できます。