Search 4 Truth

Search 4 Truth

Pythonと仮想通貨

【仮想通貨】取引所間の差額で貪欲に儲けるアービトラージに向けて【Python】

アービトラージ(裁定取引)とは

取引所によってコインの価格が違い、一番安く買える取引所で買い、一番高く売れるとろこで売ることによって差額で利益を得る手法のこと。取引所間の送金に多少の時間がかかるものの、価格が大きく変動する前に行えるため確実性が高いのが特徴。

今回やること

今回はpythonを使い各取引所の1BTCあたりの価格(ビットコイン)を取得し最適な取引所を出して差額でどのくらいの利益が出るのかを出してみます。対象となる取引所は日本国内のみ、8箇所(bitFlyer CoinCheck Zaif BTCBOX bitbank kraken QUOINEX FISCO)となります。国内には20近くの取引所がありますが今回はapiを提供している取引所に絞りました。非公式でモジュールを作っている方もいらっしゃいますが(pybitflyerなど)価格のみを取得できれば十分なのと記述方法をできるだけ統一したかったので使いませんでした。

使用した環境とモジュール

・MacBook Air Early 2015 Sierra 10.12.6
・Python 3.6.2
・iTerm2(コマンドプロント)
・requests(モジュール pip install requests でインストール)

実践

では早速やってみましょう。使うモジュールはrequestsのみです。tickerをrequestsを使いjson形式でレスポンスを得ますが、jsonはインポートしなくても使えたので下記コードには記述してません。まずは各取引所の価格を取得します。なるべく記述方法は統一しました。

import requests 

#ticker = getリクエストでjson形式でtickerが返ってきます
#price = 買値と売値を格納します 2000000.00のよう返ってくるのでintで小数点以下を切ります
#return 戻り値として上記の変数priceをタプルで戻します
#krakenの場合、文字列としての小数点が返ってくるので数値のfloatにしてからintで.0以下を切り離します

def bitflyer():
    URL = 'https://lightning.bitflyer.jp/v1/getticker'  
    ticker = requests.get(URL).json() 
    price = int(ticker['best_ask']),int(ticker['best_bid'])
    return price 
    
def coincheck():
    URL = 'https://coincheck.com/api/ticker'
    ticker = requests.get(URL).json() 
    price = int(ticker['ask']),int(ticker['bid'])
    return price

def zaif():
    url = 'https://api.zaif.jp/api/1/ticker/btc_jpy'
    ticker = requests.get(url).json()
    price = int(ticker['ask']),int(ticker['bid'])
    return price
    
def btcbox():
    url = 'https://www.btcbox.co.jp/api/v1/ticker'
    ticker = requests.get(url).json()
    price = int(ticker['buy']),int(ticker['sell'])
    return price

def bitbank():
    URL = 'https://public.bitbank.cc/btc_jpy/ticker'
    ticker = requests.get(URL).json()['data']
    price = int(ticker['buy']),int(ticker['sell'])
    return price

def kraken():
    url = 'https://api.kraken.com/0/public/Ticker?pair=XXBTZJPY'
    ticker = requests.get(url).json()['result']['XXBTZJPY']
    price = int(float(ticker['a'][0])),int(float(ticker['b'][0]))
    return price

def quoinex():
    url = 'https://api.quoine.com/products/5'
    ticker = requests.get(url).json()
    price = int(ticker['market_ask']),int(ticker['market_bid'])
    return price

def fisco():
    url = 'https://api.fcce.jp/api/1/ticker/btc_jpy'
    ticker = requests.get(url).json()
    price = int(ticker['ask']),int(ticker['bid'])
    return price


取引所ごとに関数を作りました。まとめて出力するとこんな感じ。買値と売値が格納された変数priceが戻り値とします。戻り値が複数あるのでタプルとして戻ります。

f:id:lisbeths:20180108231051p:plain


x = [bitflyer(),coincheck(),zaif(),btcbox(),bitbank(),kraken(),quoinex(),fisco()]
store = ['bitflyer','coincheck','zaif','btcbox','bitbank','kraken','quoinex','fisco']

#変数xに全ての取引所の買値と売値をリストで格納します
#変数storeには全ての取引所の名前をリストで格納します 

ask,bid = [],[]

#リストaskとリストbidを定義しておきます

for i in x:
    ask.append(i[0])
    bid.append(i[1])

#askとbidにxに格納した買値と売値を追加していきます

リストaskとbidを出力させてみました。見づらいですが、買値と売値に振り分けられていることがわかります。

f:id:lisbeths:20180108231741p:plain

dic = {} #辞書dicを定義
count = 0 #カウンター用の変数countに数値0を代入
for i in store: 
    dic.update({ask[count]:i}) 
    #辞書dicに買値が格納された変数askをキーとして前に定義してあった変数storeを順番に値としていきます
    #これにより価格と取引所の名前が紐付きました
    count += 1 #askのリストを順番に出すためのカウンターです 
ask_num = sorted(ask)[0] #変数ask_numにはリストaksを昇順ソートし最前にきたものを格納
best_ask = dic[ask_num] #変数ask_numをdicのキーとして入れると買値が一番安い取引所が出力されます 

#同じように売値でも
dic = {}
count = 0
for i in store:
    dic.update({bid[count]:i})
    count += 1
bid_num = sorted(bid,reverse=True)[0] #降順でソートし最前のものを格納
best_bid = dic[bid_num]

最適価格とその取引所名がわかりました。最後に計算をして終わります。

#文字列として一番安く買える取引所と一番安く高く売れる取引所を出力
#最高価格の売値と最低価格の買値を引いて区切り点をつけるフォーマットをしました
print(best_ask + ' で買い ' + best_bid + ' で売ると ' + str("¥{:,d}".format(bid_num - ask_num)) + ' の利益')

実行してみました。価格は売買手数料や送金手数料を加味していません。現在1BTCあたりの価格が200万前後なのでこの額でアビトラして単純計算でこのくらいになるよ〜というものです。

f:id:lisbeths:20180108234154p:plain

今回使用したコードはgithubにアップしておいたので、こっちを貼り付けて実行するほうがはやいです。

ビットコインの最適価格を出すやつ(アビトラ用)