見出し画像

複数取引所データ収集&加工ツール「DataTools」

BitMEX、bitFlyer、Bitfinexなどのデータ取得・加工を共通化してまとめたpythonクラスです。

各取引所ごとのAPI呼び出しやデータフォーマットの違いはDataTools内で編集しているため、呼び出し関数も戻り値も同じ形で扱うことができます。
また、取得したデータを日付型変換や時系列操作、集計・ソートなど分析やデータ加工でよく使う機能を関数化しています。

本ツールはBOT開発や検証、バックテストなどにおいて煩雑なデータ取得や加工を簡略化し、本来の目的に注力できるよう支援するツールとなっています。

そのため、時系列データ可視化ツール「ChartCreator」を使用する場合においても、とても相性の良いツールとなります。

【0. 目次】

■ 1. 機能概要
■ 2. 初期設定
■ 3. 機能詳細
■ 4. 使用例(jupyter notebook)
■ 5. 注意事項
■ 6. DataToolsに含まれるもの

【1. 機能概要】

■ BitMEX/bitFlyer/BitfinexからREST API経由で各種データを取得
 (約定履歴、OHLCV、オーダーブック、各種価格、残高 etc.)
■ Datetime/UnixTime/日付文字列を単項目 or リストでまとめて相互変換
■ 時系列データの集計・ソート・反転などの加工
 (約定履歴→OHLCV、OHLCV時間足変換、指定列でソート etc.)

【2. 初期設定】

本ツールの動作環境はpython3となります。
もしない場合は、以下を参考にpython3の環境構築を行ってください。

python 開発環境構築手順(Windows)
python 開発環境構築手順(Mac)
python 開発環境構築手順(AWS)


① 必要なパッケージをインストールします。

pip install numpy pandas datetime requests simplejson bitmex pybitflyer

②「data_tools.py」ファイルを適切なディレクトリに配置します。
 特にこだわりがなければ実行するpythonスクリプトファイルと同じディレクトリで問題ありません。
(DataToolsはこの1ファイルで完結しているため、他は不要です。)

③ BitMEX/bitFlyerのAPI KeyとAPI Secretをdata_tools.pyに設定します。
 data_tools.pyの30行目あたりに設定項目があります。
 (1ファイルで扱えるようにAPI KEY情報もコードに内包しています。
  外部ファイルなどに切り離したい場合は変更してください。)
 ※自注文履歴やポジション・残高取得が不要な場合はAPI Keyを
  設定しなくても動作します。

#=================================================================
#【DataTools】
#=================================================================
class DataTools(object):
    """
    データ取得・加工サポートクラス
    """

    # 設定情報
    config = {
        Exchange.BitMEX : {
            "api_key"    : "", #<--ここにBitMEX API Keyを記入してください。
            "api_secret" : "", #<--ここにBitMEX API Secretを記入してください。
            "symbol"     : "XBTUSD",
        },
        Exchange.bitFlyer : {
            "api_key"    : "", #<--ここにbitFlyer API Keyを記入してください。
            "api_secret" : "", #<--ここにbitFlyer API Secretを記入してください。
            "symbol"     : "FX_BTC_JPY",
        },
    }

④ 使用するコード内で「Exchange」「DataTools」をimportします。
(必要に応じてリネームしてください。
 本note内ではExchangeを"exc"、DataToolsを"dtl"として扱っていきます。)

from data_tools import Exchange as exc  # 取引所Enumクラス
from data_tools import DataTools as dtl # データ取得・編集ツールクラス

【3. 機能詳細】

DataToolsに用意されている全機能(関数)の一覧になります。
具体的な使い方は後述の「4. 使用例」を参考にしてください。

#===============================================================================
# [関数一覧]
#===============================================================================
    #---------------------------------------------------------------------
    # APIオブジェクト取得
    #---------------------------------------------------------------------
    # 対象取引所(BitMEX, bitFlyer)
    #---------------------------------------------------------------------
    # [@param]
    #   exchange(Exchange(enum)) 処理対象取引所
    # [return]
    #   API(object)
    #---------------------------------------------------------------------
    def API(exchange=Exchange.BitMEX)

    #---------------------------------------------------------------------
    # 約定履歴を取得(REST API)
    #---------------------------------------------------------------------
    # 対象取引所(BitMEX, bitFlyer)
    #---------------------------------------------------------------------
    # [@param]
    #   exchange(Exchange(enum))    処理対象取引所
    #   ut_from(int)                取得開始 UnixTime (None : 1時間前時刻)
    #   ut_to(int)                  取得終了 UnixTime (None : 現在時刻)
    #   reverse(bool)               並び順(True:新->古, False:古->新)
    #   tstype(string)              timestampデータ型
    #                                   "UTMS":UnixTime(ミリ秒)
    #                                   "UTS" :UnixTime(秒)
    #                                   "DT"  :datetime
    #                                   "STMS":日付文字列(%Y-%m-%dT%H:%M:%S.%fZ)
    #                                   "STS" :日付文字列(%Y-%m-%dT%H:%M:%S)
    # [return]
    #   DataFrame
    #   columns=["timestamp", "side", "price", "size"]
    #---------------------------------------------------------------------
    def get_trades(exchange=Exchange.BitMEX, ut_from=None, ut_to=None, reverse=False, tstype="UTS")

    #---------------------------------------------------------------------
    # 自注文の約定履歴を取得(REST API)
    #---------------------------------------------------------------------
    # 対象取引所(BitMEX, bitFlyer)
    #---------------------------------------------------------------------
    # [@param]
    #   exchange(Exchange(enum))    処理対象取引所
    #   ut_from(int)                取得開始 UnixTime (None : 1時間前時刻)
    #   ut_to(int)                  取得終了 UnixTime (None : 現在時刻)
    #   reverse(bool)               並び順(True:新->古, False:古->新)
    #   tstype(string)              timestampデータ型
    #                                   "UTMS":UnixTime(ミリ秒)
    #                                   "UTS" :UnixTime(秒)
    #                                   "DT"  :datetime
    #                                   "STMS":日付文字列(%Y-%m-%dT%H:%M:%S.%fZ)
    #                                   "STS" :日付文字列(%Y-%m-%dT%H:%M:%S)
    # [return]
    #   DataFrame
    #   columns=["timestamp", "side", "price", "size", "comm"]
    #---------------------------------------------------------------------
    def get_executions(exchange=Exchange.BitMEX, ut_from=None, ut_to=None, reverse=False, tstype="UTS")

    #---------------------------------------------------------------------
    # 証拠金の変動履歴を取得(REST API)
    #---------------------------------------------------------------------
    # 対象取引所(bitFlyerのみ)
    #---------------------------------------------------------------------
    # [@param]
    #   ut_from(int)                取得開始 UnixTime (None : 1時間前時刻)
    #   ut_to(int)                  取得終了 UnixTime (None : 現在時刻)
    #   reverse(bool)               並び順(True:新->古, False:古->新)
    #   tstype(string)              timestampデータ型
    #                                   "UTMS":UnixTime(ミリ秒)
    #                                   "UTS" :UnixTime(秒)
    #                                   "DT"  :datetime
    #                                   "STMS":日付文字列(%Y-%m-%dT%H:%M:%S.%fZ)
    #                                   "STS" :日付文字列(%Y-%m-%dT%H:%M:%S)
    # [return]
    #   DataFrame
    #   columns=["timestamp", "change", "amount"]
    #---------------------------------------------------------------------
    def get_collaterals(ut_from=None, ut_to=None, reverse=False, tstype="UTS")

    #---------------------------------------------------------------------
    # OHLCVをDataFrameで取得(REST API)
    #---------------------------------------------------------------------
    # 対象取引所(BitMEX, bitFlyer, Bitfinex)
    #---------------------------------------------------------------------
    # [@param]
    #   exchange(Exchange(enum))    処理対象取引所
    #   period(string)              時間足(1m, 3m, 5m, 15m, 30m, 1h, 2h, 3h, 4h, 6h, 8h, 12h, 1d)
    #   count(int)                  取得行数
    #   reverse(bool)               並び順(True:新->古, False:古->新)
    #   tstype(string)              timestampデータ型
    #                                   "UTMS":UnixTime(ミリ秒)
    #                                   "UTS" :UnixTime(秒)
    #                                   "DT"  :datetime
    #                                   "STMS":日付文字列(%Y-%m-%dT%H:%M:%S.%fZ)
    #                                   "STS" :日付文字列(%Y-%m-%dT%H:%M:%S)
    # [return]
    #   DataFrame
    #   columns=["timestamp", "open", "high", "low", "close", "volume"]
    #---------------------------------------------------------------------
    def get_ohlcv(exchange=Exchange.BitMEX, period="1m", count=1000, reverse=False, tstype="UTS")

    #---------------------------------------------------------------------
    # OHLCVの列を指定して取得(REST API)
    #---------------------------------------------------------------------
    # 対象取引所(BitMEX, bitFlyer, Bitfinex)
    #---------------------------------------------------------------------
    # [@param]
    #   exchange(Exchange(enum))    処理対象取引所
    #   period(string)              時間足(1m, 3m, 5m, 15m, 30m, 1h, 2h, 3h, 4h, 6h, 8h, 12h, 1d)
    #   col(string)                 取得する列名
    #   count(int)                  取得行数
    #   reverse(bool)               並び順(True:新->古, False:古->新)
    # [return]
    #   ndarray
    #---------------------------------------------------------------------
    def get_ohlcv_col(exchange=Exchange.BitMEX, period="1m", col="close", count=1000, reverse=False)

    #---------------------------------------------------------------------
    # 現在の残高情報を取得(REST API)
    #    (private : api_key未設定は取得不可)
    #---------------------------------------------------------------------
    # 対象取引所(BitMEX, bitFlyer)
    #---------------------------------------------------------------------
    # [@param]
    #   exchange(Exchange(enum)) 処理対象取引所
    # [return]
    #   float/int
    #---------------------------------------------------------------------
    def get_balance(exchange=Exchange.BitMEX)

    #---------------------------------------------------------------------
    # 現在のポジション情報を取得(REST API)
    #    (private : api_key未設定は取得不可)
    #---------------------------------------------------------------------
    # 対象取引所(BitMEX, bitFlyer)
    #---------------------------------------------------------------------
    # [@param]
    #   exchange(Exchange(enum)) 処理対象取引所
    # [return]
    #   dict{"size", "avr_entry"}
    #---------------------------------------------------------------------
    def get_position(exchange=Exchange.BitMEX)

    #---------------------------------------------------------------------
    # 現在の価格情報を取得(REST API)
    #---------------------------------------------------------------------
    # 対象取引所(BitMEX, bitFlyer, Bitfinex)
    #---------------------------------------------------------------------
    # [@param]
    #   exchange(Exchange(enum)) 処理対象取引所
    # [return]
    #   dict{"last", "bid", "ask"}
    #---------------------------------------------------------------------
    def get_ticker(exchange=Exchange.BitMEX)

    #---------------------------------------------------------------------
    # 現在のオーダーブック情報を取得(REST API)
    #---------------------------------------------------------------------
    # 対象取引所(BitMEX, bitFlyer, Bitfinex)
    #---------------------------------------------------------------------
    # [@param]
    #   exchange(Exchange(enum))    処理対象取引所
    #   depth(int)                  bids/asksをそれぞれ取得する件数
    # [return]
    #   dict{"bids":[["price", "size"]], "asks":[["price", "size"]]}
    #---------------------------------------------------------------------
    def get_orderbook(exchange=Exchange.BitMEX, depth=10)

    #---------------------------------------------------------------------
    # datetimeを文字列変換
    #---------------------------------------------------------------------
    # [@param]
    #   dt(datetime or list or Series) 変換するdatetime(単項目 or 複数一括)
    #   fmt(string)                    変換する文字列フォーマット
    # [return]
    #   string(単項目 or 複数一括)
    #---------------------------------------------------------------------
    def dt_to_str(dt, fmt="%Y-%m-%dT%H:%M:%S.%fZ")

    #---------------------------------------------------------------------
    # 日付文字列をdatetime変換
    #---------------------------------------------------------------------
    # [@param]
    #   str_dt(string or list or Series) 変換する日付文字列(単項目 or 複数一括)
    #   fmt(string)                      変換する文字列フォーマット
    #   tz(string)                       設定するタイムゾーン(入力時のみ設定)
    # [return]
    #   datetime(単項目 or 複数一括)
    #---------------------------------------------------------------------
    def str_to_dt(str_dt, fmt="%Y-%m-%dT%H:%M:%S.%fZ", tz=None)

    #---------------------------------------------------------------------
    # datetimeをUnixTime変換
    #---------------------------------------------------------------------
    # [@param]
    #   dt(datetime or list or Series) 変換するdatetime(単項目 or 複数一括)
    #   unit(string)                   "s"[sec], "ms"[msec]
    # [return]
    #   int(単項目 or 複数一括)
    #---------------------------------------------------------------------
    def dt_to_ut(dt, unit="s")

    #---------------------------------------------------------------------
    # UnixTimeをdatetime変換
    #---------------------------------------------------------------------
    # [@param]
    #   ut(int or list or Series) 変換するUnixTime(単項目 or 複数一括)
    #   unit(string)              "s"[sec], "ms"[msec]
    #   tz(string)                設定するタイムゾーン(入力時のみ設定)
    # [return]
    #   datetime(単項目 or 複数一括)
    #---------------------------------------------------------------------
    def ut_to_dt(ut, unit="s", tz=None)

    #---------------------------------------------------------------------
    # timestampを指定period単位に丸める(切り捨て)
    #   指定したtimestamp列を期間丸めした値に置換
    #   timestamp列はUnixTimeでもDatetimeでも変換可能
    #---------------------------------------------------------------------
    # [@param]
    #   df(DataFrame)   変換するtimestampを持つDataFrame
    #   col(string)     変換するtimestamp列名(indexは"index")
    #   period(int)     丸める期間(秒)
    # [return]
    #---------------------------------------------------------------------
    def round_timestamp(df, col="index", period=60)

    #---------------------------------------------------------------------
    # OHLCVを指定期間にリサンプリング
    #---------------------------------------------------------------------
    # [@param]
    #   df(DataFrame)   変換するOHLCV("timestamp":Datetimeindexであること)
    #                    columns=["timestamp", "open", "high", "low", "close", "volume"]
    #   period(string)  指定期間("1S":1秒, "1T":1分, "1H":1時間, "1D":1日)
    #   label(string)   変換後のtimestamp("left":期間開始時刻, "right":期間終了時刻)
    # [return]
    #---------------------------------------------------------------------
    def resample_ohlcv(df, period="1H", label="left")

    #---------------------------------------------------------------------
    # 約定履歴から指定期間のOHLCVを生成
    #---------------------------------------------------------------------
    # [@param]
    #   df(DataFrame)   約定履歴("timestamp":Datetimeindexであること)
    #                    columns=["timestamp", "price", "size"]
    #   period(string)  指定期間("1S":1秒, "1T":1分, "1H":1時間, "1D":1日)
    #   label(string)   変換後のtimestamp("left":期間開始時刻, "right":期間終了時刻)
    # [return]
    #   DataFrame
    #   columns=["timestamp", "open", "high", "low", "close", "volume"]
    #---------------------------------------------------------------------
    def trades_to_ohlcv(df, period="1H", label="left")

    #---------------------------------------------------------------------
    # DataFrameをソート
    #---------------------------------------------------------------------
    # [@param]
    #   df(DataFrame)           ソートするDataFrame
    #   by(string or list)      ソートキー列名(複数はlistで指定)
    #   ascending(bool or list) True:昇順, False:降順(by列数と項目数を合わせる)
    #   reset_index(bool)       インデックスリセットするか
    # [return]
    #---------------------------------------------------------------------
    def sort_df(df, by="index", ascending=True, reset_index=False)

    #---------------------------------------------------------------------
    # DataFrameを反転
    #---------------------------------------------------------------------
    # [@param]
    #   df(DataFrame)       反転するDataFrame
    #   axis(string)        "index":行反転, "column":列反転
    #   reset_index(bool)   インデックスリセットするか
    # [return]
    #---------------------------------------------------------------------
    def reverse_df(df, axis="index", reset_index=False)

【4. 使用例】

以下のリンクにDataToolsの各関数の使用例と取得結果をまとめてあります。
また、リンク先と同様のjupyter notebookファイル(ipynb)をダウンロードファイルに同梱しています。
DataToolsの使用例はこちら

【5. 注意事項】

本ツールではpandas DataFrameを多く活用していますので、使用するにはDataFrameを扱えることが前提となります。

データ取得・加工を目的としているため、処理速度Rate Limitにはあまり配慮していません。
場合によっては約定履歴取得などにかなりの時間がかかる可能性があります。
必要に応じてcsv入出力を活用するなど工夫すると効率的です。
(bot運用への組み込みは推奨しませんが、利用する場合はご注意ください。)

自注文の約定履歴やポジション・残高取得にはAPI KEYが必要なため、設定して下さい。
(また、BitMEXではAPI KEY認証することでRate Limit上限が上がるため、
 大量データ取得時などの取得効率が上がります。)

データ収集・加工を目的としているため、注文系APIは含んでいません。

【6. DataToolsに含まれるもの】

■ data_tools.py   :本体ソース(Exchange/DataToolsクラス)
■ README.txt   :使用方法・解説etc.
■ requirements.txt :必要なパッケージ一覧
■ DataTools使用方法.ipynb:jupyter notebookの使用例

《以下、有料パートですが、解説はここまでで全てです。》

ここから先は

327字

¥ 1,000

この記事が気に入ったらサポートをしてみませんか?