ランダムウォーク・データの作成


ランダムウォーク・データの作成

ランダムウォークのデータを作成する。


環境


  • Ubuntu 18.04 LTS 64bit版

  • Jupyter Notebook 5.7.4


サンプルコード

例としてドル円をイメージして2009年1月1日から2018年12月31日までの日足のランダムウォークデータを作成する。

同期間のドル円に合わせて、90.64円からスタートし、標準偏差は日足で0.54%程度になるように設定する。また、小数点は3桁で四捨五入する。もちろんこのようにする必要はないが、普段触れている為替データに感覚的に近づけるためである。

データは例えば日足で作成したなら「RANDOM1440.csv」というファイル名で指定したフォルダーに保存される。

import numpy as np

import os
import pandas as pd
from collections import OrderedDict

# ランダムウォークデータを作成する関数を定義する。
def make_randomwalk_data(timeframe, start, end, folder, open_price=100.0,
deviation=0.01, decimal=3, seed=None):
filename = os.path.expanduser(folder+'/RANDOM'+str(timeframe)+'.csv')
# 10秒に1回、tickが動くと仮定する。
index = pd.date_range(start, end, freq='10S')
n = len(index)
if seed is not None:
np.random.seed(seed)
rnd = np.random.normal(0.0, deviation/np.sqrt(6*1440), n-1)
rnd = np.hstack([0.0, rnd])
randomwalk = rnd.cumsum() + np.log(open_price)
randomwalk = np.exp(randomwalk)
randomwalk = pd.Series(randomwalk, index=index)
randomwalk1 = randomwalk.resample('T').ohlc()
volume = pd.DataFrame(
[6]*len(randomwalk1), index=randomwalk1.index, columns=['volume'])
randomwalk1 = pd.concat([randomwalk1, volume], axis=1)
ohlcv_dict = OrderedDict()
ohlcv_dict['open'] = 'first'
ohlcv_dict['high'] = 'max'
ohlcv_dict['low'] = 'min'
ohlcv_dict['close'] = 'last'
ohlcv_dict['volume'] = 'sum'
data = randomwalk1.resample(
str(timeframe)+'T', label='left', closed='left').apply(ohlcv_dict)
data = data[data.index.dayofweek<5]
data = np.round(data, decimal)
data.to_csv(filename)

# 作成したいランダムウォークデータのタイムフレーム、期間、作成先フォルダー、
# 開始価格、標準偏差、小数点の桁数、シードを指定する。
timeframe = 1440
start = '2009.01.01 00:00'
end = '2018.12.31 23:59'
folder = '~/py/historical_data'
open_price = 90.64
deviation = 0.0054
decimal = 3
seed = 0 # 同じ結果となるよう、シードを0で設定する。
# ランダムウォークデータを作成する。
make_randomwalk_data(timeframe, start, end, folder, open_price, deviation,
decimal, seed)


確認

先ず、データの初めを見てみる。

filename = '~/py/historical_data/RANDOM1440.csv'

df = pd.read_csv(filename, index_col=0)
print(df.head())

              open    high     low   close  volume

2009-01-01 90.640 90.748 89.856 89.899 8640
2009-01-02 89.902 90.366 89.381 90.161 8640
2009-01-05 89.687 89.962 89.427 89.830 8640
2009-01-06 89.826 90.308 89.450 89.702 8640
2009-01-07 89.707 90.114 89.640 89.735 8640

ちゃんと90.64円からスタートしている。

10秒置きにデータを作成しているので、出来高は1分で6、1日で8640となる。

次にデータの終わりを見てみる。

print(df.tail())

               open     high      low    close  volume

2018-12-25 102.753 102.791 101.968 102.162 8640
2018-12-26 102.164 102.661 102.012 102.247 8640
2018-12-27 102.248 102.392 101.615 101.974 8640
2018-12-28 101.976 103.023 101.969 102.854 8640
2018-12-31 102.600 102.672 102.086 102.535 8640

10年間で90.64円から102.535円まで上昇しているが、ドル円ならいかにもありそうな価格変動である。

最後に日足でのボラティリティがどのくらいになっているかを見てみる。

cl = df.close

log_cl = cl.apply(np.log)
change = log_cl - log_cl.shift()
std = change.std()
print('std = ', std)

std =  0.006227778243675163

0.54%に指定したが0.62%とやや高めになっている。これは土日のデータを削除したときに月曜朝に窓が生じるので、それがボラティリティを若干押し上げているのだと思う。

ところでUSDJPYの同期間のボラティリティは0.62%となっている。つまり0.62%になるようにやや低めの0.54%に設定したわけである。どうでもいいことではあるが。