ヒストリカルデータの加工


ヒストリカルデータの加工

生のヒストリカルデータを使って必要な加工を施す。生のヒストリカルデータのダウンロードについては「ヒストリカルデータのダウンロード」の記事を参照。


環境


  • Ubuntu 18.04 LTS 64bit版

  • Jupyter Notebook 5.7.4


ヒストリカルデータの加工

例としてUSDJPYの生データを使い、必要な加工を施して2004年1月1日から2018年12月31日までの1時間足を作成する。

生データのファイルは「~/ダウンロード/historical_data」フォルダーにあるとする。また、加工後のファイルは「~/py/historical_data」フォルダーに保存する。加工後のファイル名はUSDJPYの1時間足であれば「USDJPY60.csv」となる。

import glob

import os
import pandas as pd
from collections import OrderedDict
from datetime import datetime, timedelta

# ヒストリカルデータを加工する関数を定義する。
def process_historical_data(symbol, timeframe, start, end, folder1, folder2):
filename1 = glob.glob(os.path.expanduser(folder1+'/'+symbol+'*.csv'))[0]
filename2 = os.path.expanduser(folder2+'/'+symbol+str(timeframe)+'.csv')
index = pd.date_range(start, end, freq=str(timeframe)+'T')
data = pd.DataFrame(index=index)
temp = pd.read_csv(filename1, index_col=0)
temp.index = pd.to_datetime(temp.index)
temp.index = temp.index + timedelta(hours=2) # NYクロージングに合わせる。
data = pd.concat([data, temp], axis=1)
label = ['open', 'high', 'low', 'close', 'volume']
data.columns = label
ohlcv_dict = OrderedDict()
ohlcv_dict['open'] = 'first'
ohlcv_dict['high'] = 'max'
ohlcv_dict['low'] = 'min'
ohlcv_dict['close'] = 'last'
ohlcv_dict['volume'] = 'sum'
data = data.fillna(method='ffill')
data = data[~data.index.duplicated()]
data = data.resample(
str(timeframe)+'T', label='left', closed='left').apply(ohlcv_dict)
data = data[data.index.dayofweek<5]
start = datetime.strptime(start, '%Y.%m.%d %H:%M')
end = datetime.strptime(end, '%Y.%m.%d %H:%M')
data = data[start:end]
data.to_csv(filename2)

# 加工したいヒストリカルデータの通貨ペア、タイムフレーム、期間、
# 加工元フォルダー、加工先フォルダーを指定する。
symbol = 'USDJPY'
timeframe = 60
start = '2004.01.01 00:00'
end = '2018.12.31 23:59'
folder1 = '~/ダウンロード/historical_data'
folder2 = '~/py/historical_data'
# ヒストリカルデータを加工する。
process_historical_data(symbol, timeframe, start, end, folder1, folder2)


加工の一括処理

複数の通貨ペア、複数の足で一括処理したい場合は以下のようにする。

例としてAUDJPY、AUDUSD、EURJPY、EURUSD、GBPJPY、GBPUSD、USDJPYの生データを使い、必要な加工を施して2004年1月1日から2018年12月31日までの1分足、5分足、15分足、30分足、1時間足、4時間足、日足を作成する。

import glob

import os
import pandas as pd
from collections import OrderedDict
from datetime import datetime, timedelta

# ヒストリカルデータを加工する関数を定義する。
def process_historical_data(symbol, timeframe, start, end, folder1, folder2):
filename1 = glob.glob(os.path.expanduser(folder1+'/'+symbol+'*.csv'))[0]
filename2 = os.path.expanduser(folder2+'/'+symbol+str(timeframe)+'.csv')
index = pd.date_range(start, end, freq=str(timeframe)+'T')
data = pd.DataFrame(index=index)
temp = pd.read_csv(filename1, index_col=0)
temp.index = pd.to_datetime(temp.index)
temp.index = temp.index + timedelta(hours=2) # NYクロージングに合わせる。
data = pd.concat([data, temp], axis=1)
label = ['open', 'high', 'low', 'close', 'volume']
data.columns = label
ohlcv_dict = OrderedDict()
ohlcv_dict['open'] = 'first'
ohlcv_dict['high'] = 'max'
ohlcv_dict['low'] = 'min'
ohlcv_dict['close'] = 'last'
ohlcv_dict['volume'] = 'sum'
data = data.fillna(method='ffill')
data = data[~data.index.duplicated()]
data = data.resample(
str(timeframe)+'T', label='left', closed='left').apply(ohlcv_dict)
data = data[data.index.dayofweek<5]
start = datetime.strptime(start, '%Y.%m.%d %H:%M')
end = datetime.strptime(end, '%Y.%m.%d %H:%M')
data = data[start:end]
data.to_csv(filename2)

# 期間、加工元フォルダー、加工先フォルダーを指定する。
start = '2004.01.01 00:00'
end = '2018.12.31 23:59'
folder1 = '~/ダウンロード/historical_data'
folder2 = '~/py/historical_data'
# ヒストリカルデータを加工する。
for symbol in ['AUDJPY', 'AUDUSD', 'EURJPY', 'EURUSD', 'GBPJPY', 'GBPUSD', 'USDJPY']:
for timeframe in [1, 5, 15, 30, 60, 240, 1440]:
process_historical_data(symbol, timeframe, start, end, folder1, folder2)


備考

①デューカスコピーのヒストリカルデータはGMT基準であるように思われる(夏時間があるようなのでUTCではない)。NYクロージング基準に変更するため、元データから2時間進ませている。

②土日以外のすべての足を作成し、データが欠けている場合は前の足のデータで補間している。データが欠けている場合はデータに変動がないと考えれば前の足の終値を使うことには問題ないが、始値、高値、安値、出来高ではそうはいかない。テクニカル指標なども、元データを使った場合と若干の違いが出ることもある。