emoiの日記

忘れっぽい雑食系エンジニアのメモblogです。仮想通貨とROSに興味があります。

bitflyerFXのSell/BuyのVolume算出

前回の記事において、いなごFlyerのスクレイピングを紹介しました。
今回はbitflyerFXに特化したものを書いてみました。

目的

  • 直近のsellおよびbuyのvolumeをお手軽に取得したい!
  • pubnubを触ってみたい。

やりたいこと

以下の約定データを使って、過去20秒間のsellおよびbuyのvolumeを算出したい。
ビットコイン取引所【bitFlyer Lightning】

コード

pythonです。

# coding: utf-8
from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNStatusCategory
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub_tornado import PubNubTornado
from pubnub.pnconfiguration import PNReconnectionPolicy
import pandas as pd
from datetime import datetime, timezone, timedelta

config = PNConfiguration()
config.subscribe_key = 'sub-c-52a9ab50-291b-11e5-baaa-0619f8945a4f'
config.reconnect_policy = PNReconnectionPolicy.LINEAR
pubnub = PubNubTornado(config)

from tornado import gen

df_all = pd.DataFrame(index=['datetime'], 
                  columns=['id', 
                           'side', 
                           'price', 
                           'size', 
                           'exec_date', 
                           'buy_child_order_acceptance_id', 
                           'sell_child_order_acceptance_id'])

@gen.coroutine #非同期処理
def main(channels):
    class BitflyerSubscriberCallback(SubscribeCallback):
        def presence(self, pubnub, presence):
            pass  # handle incoming presence data

        def status(self, pubnub, status):
            if status.category == PNStatusCategory.PNUnexpectedDisconnectCategory:
                pass  # This event happens when radio / connectivity is lost

            elif status.category == PNStatusCategory.PNConnectedCategory:
                # Connect event. You can do stuff like publish, and know you'll get it.
                # Or just use the connected event to confirm you are subscribed for
                # UI / internal notifications, etc
                pass
            elif status.category == PNStatusCategory.PNReconnectedCategory:
                pass
                # Happens as part of our regular operation. This event happens when
                # radio / connectivity is lost, then regained.
            elif status.category == PNStatusCategory.PNDecryptionErrorCategory:
                pass
                # Handle message decryption error. Probably client configured to
                # encrypt messages and on live data feed it received plain text.

        def message(self, pubnub, message):
            # Handle new message stored in message.message
            task(message.channel, message.message)

    listener = BitflyerSubscriberCallback()
    pubnub.add_listener(listener)
    pubnub.subscribe().channels(channels).execute()


def task(channel, message):
    
    for i in message:
        # print(i['exec_date'], i['side'], i['price'], i['size'])
        print(i['side'], i['size'])
        df_new = pd.DataFrame(message)
        df_new['exec_date'] = pd.to_datetime(df_new['exec_date'])

    global df_all
    df_all = df_all.append(df_new)
    df_all.index = df_all['exec_date']

    date_now = df_all.index[len(df_all)-1]
    df_lim = df_all.ix[df_all.index >= (date_now - timedelta(seconds=20))]

    buy_vol = df_lim[df_lim.apply(lambda x: x['side'], axis=1) == "BUY"]['size'].sum(axis=0)
    sell_vol = df_lim[df_lim.apply(lambda x: x['side'], axis=1) == "SELL"]['size'].sum(axis=0)

    print(df_lim.index[0].strftime('%Y-%m-%d %H:%M:%S'),
          df_lim.index[len(df_lim)-1].strftime('%H:%M:%S'),
          "BUY_VOL", format(buy_vol, '.2f'),
          "SELL_VOL", format(sell_vol, '.2f'))

if __name__ == '__main__':
    main(['lightning_executions_FX_BTC_JPY'])
    pubnub.start()

実行結果

2017-12-05 12:03:02 12:03:22 BUY_VOL 42.05 SELL_VOL 22.25

なんかそれっぽい値はできていますね。