ぷるぷるした直方体

元職業エンジニアの雑記です

取引所のAPIを使って約定データを取得するダウンローダーを公開しました

「ぼくの考えたさいきょうの取引せんりゃく」が完成したとしても、それが実際のマーケットで通用するかは不明です。 しかし、実際にトレードをすると資金がすぐ枯渇したり、限定的な期間での検証しかできません。 そこで、ヒストリカルデータを使ったバックテストを行い検証をするわけですが、そのためにはまずデータを集めないといけません。

利用するヒストリカルデータには様々な粒度が考えられます。 30日間の検証をしたいとすると、1時間足では24 * 30=720本、1分足では720 * 60= 43,200本になります。 要は非可逆圧縮されたデータなので、データ容量と検証精度はトレードオフの関係にあると考えられます。

では、非常にタイミングがシビアな取引戦略の検証には何を使うべきでしょうか? 後から取得できるデータで最小粒度は以下のような約定データです(例はbitFlyerの/executions)。

{
  "id": 39287,
  "side": "BUY",
  "price": 31690,
  "size": 27.04,
  "exec_date": "2015-07-08T02:43:34.823",
  "buy_child_order_acceptance_id": "JRF20150707-200203-452209",
  "sell_child_order_acceptance_id": "JRF20150708-024334-060234"
}

このような「いつ・どこで・どれだけ・買った/売った」という4種類の情報は、APIのある取引所なら提供していると思われます。

これを使った場合、30日間でどれだけのデータになるのでしょうか? 時期や取引所により大きく変わりますが、bitFlyerでは8,000万でした。 1分足が4万ちょいなので、約2,000倍です。

さて、これだけ大きいと当然1回のリクエストでは取得しきれません。 取得上限は大体500か1,000ですので、最低でも8万回はAPIを殴り続ける必要があります。 毎回APIから取得することもできないため、手元のストレージに溜めておく処理も要ります。

上手くクエリパラメーターを更新しないといけないですし、取引所ごとに呼び出し方法は異なり、データ形式も異なります。 あぁめんどい……。

ライブラリの説明

ということで、Rustのcrateとしてダウンローダーライブラリを公開しました。

github.com

https://crates.io/crates/pikmin

機能としては以下を備えています。

  • APIを繰り返し叩いてMySQLや標準出力等に書き込む
  • 中断からの復帰
  • traitを実装して渡すだけの簡単カスタマイズ
  • ビルトインでbitFlyer, Liquid, BitMEXのダウンローダー付き

下記それぞれを個別に実装することで、お好みの動作に変更できます。

  • 取引所APIからの取得
  • 約定データ書き込み
  • 進捗書き込み

例えば、Binanceのデータを取りたい時は、APIからの取得部分を実装して渡すだけです。 書き出し先をMySQLにするかCSVにするかや、 GCP上で動かす場合は進捗書き込みレイヤーをCloud Storageにするなど、 環境に応じて最小限の記述で済みます。

詳しくはdocをどうぞ。

crateの公開について

初crateのpublishでしたが、ドキュメント・CIの設定やツール類が整っており比較的快適でした。 特にTravisCIを使う場合は、先人の.travis.ymlを移植するだけで済みます。 また、cargo-releaseを使うとバージョンアップの処理を自動化でできます。

rust-lang-nursery.github.io

docコメントが無い箇所や冗長な記述を検出するため、事前に下記のようなwarningやClippyによるlintを掛けておくと良いでしょう。

#![warn(
  missing_debug_implementations,
  missing_docs,
  trivial_numeric_casts,
  unsafe_code,
  unused_extern_crates,
  unused_import_braces,
  unused_qualifications)
]
#![deny(clippy::pedantic)]
#![deny(warnings)]
#![allow(clippy::doc_markdown)]
#![allow(clippy::stutter)]
#![allow(clippy::cast_precision_loss)]
#![allow(clippy::cast_sign_loss)]
#![allow(clippy::cast_possible_wrap)]

まとめ

バックテストの第一ステップである取引データの取得を簡単にするため、共通処理をライブラリとしました。 また、レイヤーを切っているため、拡張性を持たせて環境依存の処理がしやすいようにしています。

もし需要があればご利用ください。