バックテスト・学習でデータを使うにも、サーバから逐次ダウンロードしているのでは、遅延や負荷がかかります。 ここでは取得したローソク足をMongoDBにストックし、またMongoDBからデータを取得します。
MongoDBを入れます。ここではdocker上で展開を行います。
$ docker pull mongo
$ docker run -p 27017:27017 --name oanda-mongo -d mongo
Python用のパッケージもインストールします。
(venv) $ pip install pymongo
今回は、指定した日から現在までのローソク足を取得するプログラムを作成します。
import v20
import pymongo
import yaml
from datetime import datetime
MONGO_URL = 'mongodb://localhost:27017/'
AUTH_PATH = "auth.yaml"
ACCOUNT_TYPE = "live"
DATETIME_FROM = datetime(2017, 1, 1)
with open(AUTH_PATH, "r") as f:
auth = yaml.safe_load(f)
def candle_store(instrument, granularity):
client = pymongo.MongoClient(MONGO_URL)
database = client[ACCOUNT_TYPE]
key = instrument + "." + granularity
collection = database[key]
collection.create_index(
[
("unixtime", 1),
],
unique=True,
)
api = v20.Context(
auth[ACCOUNT_TYPE]["url"],
auth[ACCOUNT_TYPE]["port"],
token=auth[ACCOUNT_TYPE]["token"],
)
while True:
latest = collection.find_one(sort=[("unixtime", pymongo.DESCENDING)])
if latest:
dt_from = datetime.utcfromtimestamp(latest["unixtime"])
print(key, dt_from)
else:
dt_from = DATETIME_FROM
data = {
'price': 'BA', # bid mid ask
'granularity': granularity,
'count': 5000,
'fromTime': api.datetime_to_str(dt_from),
}
response = api.instrument.candles(instrument, **data)
if response.status != 200:
print(key, 'error', response, response.body)
return
candles = response.body['candles']
for candle in candles:
if not candle.complete:
print(key, "complete")
return
d = candle.dict()
d.pop("complete")
unixtime = datetime.strptime(
candle.time[:-11], '%Y-%m-%dT%H:%M:%S'
).timestamp()
d.update({"unixtime": unixtime})
try:
collection.insert_one(d)
except pymongo.errors.DuplicateKeyError:
pass
instruments = [
'USD_JPY', 'EUR_JPY', 'AUD_JPY',
'EUR_USD', 'AUD_USD', 'EUR_AUD',
]
granularitys = [
'D', 'H4', 'H1', 'M15', 'M1', 'S5'
]
for instrument in instruments:
for granularity in granularitys:
candle_store(instrument, granularity)
上記コードで2017年からの現在までのローソク足データをMongoDBに保存できます。
なおスプレッド等の情報がデモアカウントと実際の取引アカウントでは異なるため、 バックテスト等に使用するデータはlive口座のものが良いです。
次にMongoDBからデータを取得します。
import pymongo
from datetime import datetime
MONGO_URL = 'mongodb://localhost:27017/'
ACCOUNT_TYPE = "live"
instrument = "USD_JPY"
granurality = "M15"
dt_from = datetime(2017, 4, 1)
dt_to = datetime(2018, 4, 1)
client = pymongo.MongoClient(MONGO_URL)
database = client[ACCOUNT_TYPE]
collection = database[instrument + "." + granurality]
cursor = collection.find({
"unixtime": {
"$gte": dt_from.timestamp(),
"$lte": dt_to.timestamp(),
}}).sort("unixtime")
for candle in cursor:
print(candle)
上記のコードで、dt_fromの日付以降、dt_toの日付以前のローソク足データが昇順で取得できます。
ローソク足に関して最も注意が必要な事は、 ローソク足の時刻以降の情報が含まれているということです。
例えば、4月1日の日足には終値、つまり4月2日の始値に近い情報が含まれています。
バックテストの際にはS5など最も細かいもので関数を回していく形になりますが、 その時点で得られないデータを使用しないよう注意が必要です。
Home > rest-live-v20 > tips > mongo
prev: 認証用ファイルの作成