取得データをMongoDBに入れる1 ローソク足

概要

バックテスト・学習でデータを使うにも、サーバから逐次ダウンロードしているのでは、遅延や負荷がかかります。 ここでは取得したローソク足を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: 認証用ファイルの作成

next: 取得データをMongoDBに入れる2 ブックデータ