In [1]:
import numpy as np
import pandas as pd

先頭148バイトはヘッダーのぶんでヘッダーの先頭4バイトに
intでヒストリファイルのバージョンが書いてある
400なら旧バージョン、401ならbuild600以降の形式
FXDDのサイトからダウンロードできるものは旧バージョンのものなので
一応両方のバージョンに対応できるように記述する

旧バージョンのものは四本値が OLHC の順で並んでいるけど
OHLC のほうが一般的な気がするのでDataFrameに変換したついでにカラムの順序を変える

In [2]:
def read_hst(filepath):
    with open(filepath, 'rb') as f:
        ver = np.frombuffer(f.read(148)[:4], 'i4')
        if ver==400:
            dtype = [('Time','u4'), ('Open','f8'), ('Low','f8'),
                     ('High','f8'), ('Close','f8'), ('Volume','f8')]
            df = pd.DataFrame(np.frombuffer(f.read(),dtype=dtype))
            df = df['Time Open High Low Close Volume'.split()]
        elif ver==401:
            dtype = [('Time','u8'), ('Open','f8'), ('High','f8'), ('Low','f8'),
                     ('Close','f8'), ('Volume','i8'), ('s','i4'), ('r','i8')]
            df = pd.DataFrame(np.frombuffer(f.read(),dtype=dtype).astype(dtype[:-2]))
        df = df.set_index(pd.to_datetime(df['Time'], unit='s')).drop('Time', axis=1)
        return df

df = read_hst('R:/work/USDJPY.hst') # これはさっきDLしたFXDDのやつ
df.head(10)
Out[2]:
Open High Low Close Volume
Time
2005-01-10 02:31:00 104.79 104.79 104.79 104.79 5.0
2005-01-10 02:32:00 104.79 104.79 104.78 104.78 6.0
2005-01-10 02:33:00 104.78 104.78 104.77 104.77 5.0
2005-01-10 02:34:00 104.77 104.79 104.77 104.79 5.0
2005-01-10 02:35:00 104.79 104.79 104.78 104.78 4.0
2005-01-10 02:36:00 104.78 104.78 104.78 104.78 2.0
2005-01-10 02:37:00 104.78 104.78 104.78 104.78 2.0
2005-01-10 02:38:00 104.78 104.78 104.78 104.78 2.0
2005-01-10 02:39:00 104.78 104.79 104.78 104.79 4.0
2005-01-10 02:40:00 104.80 104.80 104.77 104.77 5.0
In [3]:
def df_resample(df, tf='H'):
    ml = ['first', 'max', 'min', 'last', 'sum', 'last']
    kl = ['Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close']
    f = lambda k: [k, k.upper(), k.lower(), k[:1], k[:1].lower()]
    how = {key:m for k,m in zip(kl, ml) for key in f(k) if key in df.columns}
    col = [c for c in df.columns if c in how.keys()]
    return df.resample(tf).agg(how).dropna()[col]

df_m15 = df_resample(df, tf='5T')
df_m15.head()
Out[3]:
Open High Low Close Volume
Time
2005-01-10 02:30:00 104.79 104.79 104.77 104.79 21.0
2005-01-10 02:35:00 104.79 104.79 104.78 104.79 14.0
2005-01-10 02:40:00 104.80 104.80 104.74 104.74 25.0
2005-01-10 02:45:00 104.74 104.75 104.70 104.70 45.0
2005-01-10 02:50:00 104.71 104.71 104.67 104.68 46.0