今回はPythonを用いて、DukascopyからFXの過去データ(ヒストリカルデータ)をダウンロードし、読み込んでみます。他の方法については過去の記事も参照してください。
PythonでTickデータをダウンロードして読み込む
Dukascopyが提供するTickデータは1レコード20バイトの固定長データになっていて、バイトオーダーはビッグエンディアンです。データはlzmaで圧縮されており、拡張子は bi5 です。データの詳細は前回の記事を参照してください。TickデータのURLは次のようになっています。
これは2022年4月4日20時(GMT)から1時間のEURUSDのTickデータです。月の部分については 00が1月、01が2月 のようになっています。
これをPythonでダウンロードし、DataFrame
に読み込んでみます。
import lzma
import numpy as np
import pandas as pd
import urllib.request
url = 'http://datafeed.dukascopy.com/datafeed/EURUSD/2022/03/04/20h_ticks.bi5'
dt = np.dtype([('time', '>u4'), ('ask', '>u4'), ('bid', '>u4'), ('ask_volume', '>f4'), ('bid_volume', '>f4')])
req = urllib.request.Request(url)
with urllib.request.urlopen(req) as response:
with lzma.open(response) as input:
d = np.frombuffer(input.read(), dtype=dt)
df = pd.DataFrame(d)
print(df.head())
# time ask bid ask_volume bid_volume
# 0 104 109699 109697 0.12 1.80
# 1 206 109699 109696 0.12 2.70
# 2 732 109698 109695 0.98 1.80
# 3 834 109697 109694 0.90 2.70
# 4 936 109697 109693 0.90 1.44
Pythonの標準ライブラリ urllib.request
を用いてデータをダウンロードし、標準ライブラリ lzma
を用いて展開し、struct.unpack
を用いてバイト列から値を取り出します。np.dtype
の引数で各フィールドの型を指定していますが、ここで >
はビッグエンディアンであることを示し、u4 は unsigned int
(4バイト)、f4
は float
(4バイト)のフィールドであることを示します。
単位の変換
時刻はファイルの開始時刻(この例の場合は 2022-04-04 20:00:00 [3月ではないことに注意])からの経過時間で、Tickデータの場合単位はミリ秒です。価格の単位は 0.1 pips のため、EURUSDの場合は100000で割ると本来の値になります。Volume は100万単位です。単位の変換処理を含めて関数にまとめると以下のようになります。
import lzma
import numpy as np
import pandas as pd
import urllib.request
def download_data(pair, year, month, day, time, pipvalue=0.0001, volume=1000000):
url = f'http://datafeed.dukascopy.com/datafeed/{pair}/{year:04d}/{month - 1:02d}/{day:02d}/{time:02d}h_ticks.bi5'
dt = np.dtype([('time', '>u4'), ('ask', '>u4'), ('bid', '>u4'), ('ask_volume', '>f4'), ('bid_volume', '>f4')])
try:
req = urllib.request.Request(url)
with urllib.request.urlopen(req) as response:
with lzma.open(response) as input:
d = np.frombuffer(input.read(), dtype=dt)
df = pd.DataFrame(d)
origin = f'{year:04d}-{month:02d}-{day:02d} {time:02d}:00:00'
df['time'] = pd.to_datetime(df['time'], unit='ms', origin = origin)
df['ask'] *= pipvalue / 10
df['bid'] *= pipvalue / 10
df['ask_volume'] = round(df['ask_volume'] * volume)
df['bid_volume'] = round(df['bid_volume'] * volume)
return df
except Exception as e:
print(f"An error occurred: {e}")
return None
df = download_data('EURUSD', 2022, 4, 4, 20)
print(df.head())
# time ask bid ask_volume bid_volume
# 0 2022-04-04 20:00:00.104 1.09699 1.09697 120000.0 1800000.0
# 1 2022-04-04 20:00:00.206 1.09699 1.09696 120000.0 2700000.0
# 2 2022-04-04 20:00:00.732 1.09698 1.09695 980000.0 1800000.0
# 3 2022-04-04 20:00:00.834 1.09697 1.09694 900000.0 2700000.0
# 4 2022-04-04 20:00:00.936 1.09697 1.09693 900000.0 1440000.0
このように、Pythonを使うことで簡単にDukascopyのFX過去データを読み込むことができます。
コメント