Python
api
Bitcoin
自動取引

Pythonで仮想通貨自動取引 (1) : 板情報取得と各取引所のレスポンスタイム計測

初Qiitaです。よろしくお願いします。

PythonでBitcoinの自動取引ツールを作ったので、少しずつTipsを上げていく。Bitcoinなどの仮想通貨取引所はAPIを公開しているため、プログラミングの心得があると比較的簡単に自動取引ができる。まずは、基本のき、板情報の取得から。これは、ブラウザでもURLを叩けば取得可能で、試しにこちらのURLをリクエストしてみて頂きたい。

https://api.zaif.jp/api/1/depth/btc_jpy

上半分が"asks"、下半分が"bids"である。板情報など、個人のアカウントに紐付かないものは、特にトークンを取得しなくても利用できる。各Listの内容は、左が1BTCの価格で、右がその量である。

次に、Pythonで取得する場合のコードを以下に添付する。 Versionは3.5.2を使用。

import json
import requests

def board():

    URL={'bitFlyer':'https://api.bitflyer.jp/v1/getboard?product_code=BTC_JPY',
    'Quoine':'https://api.quoine.com/products/5/price_levels',
    'Zaif' : 'https://api.zaif.jp/api/1/depth/btc_jpy',
    'Coincheck':'https://coincheck.com/api/order_books'}

    bf = requests.get(URL['bitFlyer']).json()
    qo = requests.get(URL['Quoine']).json()
    zf = requests.get(URL['Zaif']).json()
    cc = requests.get(URL['Coincheck']).json()
    return (bf,qo,zf,cc)

### main ###
bd = board()
### example bitFlyer most expensive bid ###
print (bd[0]['bids'][0])
### example Quoine chapest ask ###
print (bd[1]['asks'][0])

実行結果

['1118646.0', '0.08'] 
['1118967.0', '0.011']

bd[]にJSON形式で格納されるので、簡単に取り出せる。Dataの内容は各取引所のAPI仕様書を参照のこと。

レスポンスタイム計測

以上で、各取引所の価格とSizeを取得可能である。
しかし、板情報を取得して実際に売り買いするまでの時間が長いと、約定しない確立が高くなる。従って、自動取引システムを構築する場合、取得に長い時間を要してしまった板情報は過去のものと諦め、再度取得した方が安全である。参考までに、各取引所のレスポンスタイムを計測してみた。4つずらっと並べて書いてしまったけど、こうして見るとFor文使えばよかったな、、。

import json
import requests
import time
import sys

def mj():

    URL={'bitFlyer':'https://api.bitflyer.jp/v1/getboard?product_code=BTC_JPY',
    'Quoine':'https://api.quoine.com/products/5/price_levels',
    'Zaif' : 'https://api.zaif.jp/api/1/depth/btc_jpy',
    'Coincheck':'https://coincheck.com/api/order_books'}

    #### init ###
    cc = 0
    bf = 0
    zf = 0
    qn = 0
    ccmax = 0
    ccmin = 999
    qnmax = 0
    qnmin = 999
    zfmax = 0
    zamin = 0
    bfmax = 0
    bfmin = 999

    ### number of repeat ###
    repeattime = 20

    for x in range(repeattime):
        #実行中表示
        sys.stdout.write(".")
        sys.stdout.flush()

        start = time.time()
        rt = requests.get(URL['Coincheck']).json()
        rtt = time.time() - start
        cc = cc + rtt
        if rtt > ccmax:
            ccmax = rtt
        if rtt < ccmin:
            ccmin = rtt

        start = time.time()
        rt = requests.get(URL['Quoine']).json()
        rtt = time.time() - start
        qn = qn + rtt
        if rtt > qnmax:
            qnmax = rtt
        if rtt < qnmin:
            qnmin = rtt

        start = time.time()
        rt = requests.get(URL['Zaif']).json()
        rtt = time.time() - start
        zf = zf + rtt
        if rtt > bfmax:
            zfmax = rtt
        if rtt < bfmin:
            zfmin = rtt

        start = time.time()
        rt = requests.get(URL['bitFlyer']).json()
        rtt = time.time() - start
        bf = bf + rtt
        if rtt > bfmax:
            bfmax = rtt
        if rtt < bfmin:
            bfmin = rtt

    print()
    print ("cc ave:" + str(round(cc/repeattime,5)) + " min:" + str(round(ccmin,5)) + " max:" +str(round(ccmax,5)))
    print ("qn ave:" + str(round(qn/repeattime,5)) + " min:" + str(round(qnmin,5)) + " max:" +str(round(qnmax,5)))
    print ("zf ave:" + str(round(zf/repeattime,5)) + " min:" + str(round(zfmin,5)) + " max:" +str(round(zfmax,5)))
    print ("bf ave:" + str(round(bf/repeattime,5)) + " min:" + str(round(bfmin,5)) + " max:" +str(round(bfmax,5)))

do = mj()

実行結果

....................
cc ave:0.08439 min:0.06939 max:0.11674
qn ave:0.87082 min:0.08517 max:2.74162
zf ave:0.09891 min:0.09182 max:0.16618
bf ave:0.30659 min:0.09229 max:2.1926

上の実行結果は、最大でも2.7秒と比較的安定しているが、長い場合5秒以上待つことがある。板の最安値、最高値を取りに行く勝負で5秒も遅れてしまっては駄目で、間違えてもその様な瞬間に売り買いしてはいけない。取引所のレスポンスは、その時々で変わるから実際に試してみて欲しい。尚、実行中に .... と表示させるのに意外と苦労して、こちらの記事に助けて頂いた。@airtoxinさん、ありがとうございました。

https://qiita.com/airtoxin/items/bb445529c94d3cd871f3

ではまた次回。