・ビットコインの自動アービトラージをやりたい
・趣味で仮想通貨の自動売買 bot を作りたい
・Pythonの勉強がてらビットコインの売買プログラムを作りたい
こういった思いを持つ読者に向けて記事を書いていきます。・趣味で仮想通貨の自動売買 bot を作りたい
・Pythonの勉強がてらビットコインの売買プログラムを作りたい
この記事の内容
・そもそもアービトラージ(裁定取引)とは何なのか?・なぜ現実にはアービトラージは必勝ではないのか
・アービトラージ取引のシミュレータープログラム(Python)を公開
注意
今回のコードは、
あくまでも、裁定取引のロジックの書き方の雰囲気を掴んでもらうことを目的としたシミュレーションです。
実際に売買を動作させる方法は、下の記事を参考にしてみてください(こちらは裁定取引ではありませんが)。
今回のコードは、
あくまでも、裁定取引のロジックの書き方の雰囲気を掴んでもらうことを目的としたシミュレーションです。
実際に売買を動作させる方法は、下の記事を参考にしてみてください(こちらは裁定取引ではありませんが)。
目次
裁定取引(アービトラージ)とは
念のため、そもそも裁定取引(アービトラージ)とは何なのかを復習しておきましょう。一言で言うと、裁定取引とは何らかの資産をある場所で安く買い、別の場所で高く売ることです。
例えば仮想通貨はいろいろな取引所で取引されていますよね。
私達は bitFlyer でビットコインを買うこともできますし、コインチェックで購入することもできます。
ここで重要なのは、コインチェックが売買されるレートは取引所によって微妙に異なっているということです。
例えばコインチェックでは1ビットコインが300万円の時に、 GMOコインでは350万円で取引されているということがありえるわけです(現実的にはここまで極端な価格差はほぼありませんが)。
この状況であれば、コインチェックで1 Bitcoin を購入し、それをそのまま GMO コインの口座に送って売却すればノーリスクで50万円手に入りますね。
この状況であれば、コインチェックで1 Bitcoin を購入し、それをそのまま GMO コインの口座に送って売却すればノーリスクで50万円手に入りますね。
通常の投資と違い、この作業では(原理上)損する可能性が存在しません。
みなさんも、アービトラージ取引は理論上絶対に勝てるなどと言われるのを聞いたことがあるかもしれません。
もし必勝法なのであれば、プログラムから高速で何度も何度も裁定取引を続ければ、めちゃくちゃ儲かる気がしますよね。
しかし、現実にはアービトラージ取引は100%儲かるわけではありません。
現実には必勝ではない理由
裁定取引が実際には必勝法ではない理由をまとめておきます。仮想通貨の売買手数料
まずは仮想通貨の売買に手数料生じるという問題があります。通常、取引所間の価格差はごくわずかなものです。 10%も20%も価格差があるということはまずないでしょう。
すると必然、アービトラージ取引では小さなサヤ抜きを積み重ねていくことになります。
一回一回の利益が小さいので、相対的に取引手数料の負担が大きくなるんですね。
もっともこの問題は、取引手数料が無料になる取引所と通貨のペアを選択すればクリアできます。
冒頭で紹介した記事でも、この点に注意して取引所を選択しています。
取引所のエラー
二つ目の問題は取引所のエラーです。これが最も厄介な問題かもしれません。
実際にやると分かりますが、プログラムから注文の命令を出しているのに、取引所が正常に反応してくれないことがあります。
注文が素早く正確に処理されないと、せっかく発生した価格差が消滅して損害が生じる可能性があります。
この問題は私たち側の問題というよりは、取引所が抱えている問題です。
それゆえに私たちの力で完全に解決することができません。
サーバーの反応が安定している取引所を選択することでリスクを抑えることが精一杯です。
送金手数料
また送金手数料の問題もあります。先ほどの説明では取引所Aで300万円でビットコインを購入し、取引所Bに送金後売却すると言いました。
が、現実には取引所間で仮想通貨を送金する時に手数料が発生します。
この問題を解決(緩和)するには、
・送金手数料が安いところを使う
・送金しない
という二つの方法があります。・送金しない
前者は当たり前すぎるので、後者について解説します。
まず、取引所AとBの両方に最初から現金とビットコインを十分な量保持しておきます。
そして先ほどと同じように、それぞれでのビットコイン価格が以下のようになったとします。
取引所A:300万円
取引所B:350万円
この時に、すぐさま取引所Aで1ビットコイン購入し、取引所Bで1ビットコイン売却しておきます。取引所B:350万円
その後、時間が経過し価格差が0になった時点でそれぞれの取引所で反対売買すれば、トータルで50万円儲かったことになります。
なお2つの取引所の価格差がなくなりさえすれば、最終的なビットコインの価格はいくらでも問題ありません。
ただこの対抗策にもデメリットがあります。
まずはじめに、ビットコインの現物を二つの取引所で保有する都合上、長期的にビットコインの価格が下落するリスクを負います。
ビットコイン価格が下落すると、個別の取引とは関係なく資産が減ってしまいますからね。
そのリスクを避けるためには、ビットコインFXなどで空売りを活用する必要があります。
(なお、ビットコイン自体が値上がりすると考えている場合はそもそもこのリスクは気にする必要はありません)
税金
最後に税金の問題もありますね。仮想通貨の取引でも儲かれば当然税金を納めなければいけません。
仮想通貨の税金の話は正直僕もあまり詳しくないので割愛しますが、仮想通貨で大金をせしめようと考えている人は必ずよく調べておいてください。
以上が裁定取引が現実的に必勝ではない理由です。
とはいえ、それでも上手い方法が無いのか試行錯誤することは楽しいですし、裁定取引のコードを書いてみるのは勉強にもなります。
ということで、ここからは Python によるアービトラージのデモコードを公開します。
プログラムを実運用するまでの下準備
まずはアービトラージのプログラムを実行するための下準備から解説していきます。やることは基本的に
・Pythonと必要ライブラリのインストール
・APIキーの発行
の二つだけです。・APIキーの発行
必要ライブラリといっても、取引所の API のラッパーとpandasが入っていれば大体は事足ります。
両方とも、基本的にpipでインストールすることが可能なので3分もかからないでしょう。
なので実質やることは API キーの発行だけですね。
こちらについては下の記事の一部で画像付きで詳しく解説しています。 なお今回のコードはデモであり、実際の取引所の価格データなどは使用しません。
なので、この記事のコードを動かすだけならAPIキーを発行する必要はありません。
デモコード公開
さてここまで長くなりましたが、アービトラージ取引の雰囲気をつかむためのデモコードを公開していきます。プログラムの動作と注意点
公開の前にプログラムの動作を簡単に説明しておきましょう。今回のプログラムの動作
・乱数で二つの取引所の価格データをたくさん生成(デフォルトで1000時点ずつ)・各時点で価格差が開いていれば、安い取引所で購入した高い取引所で売却する
・その後価格差が縮まっていれば反対売買する
実際にはどんな名前にしても問題ありません。
今回のプログラムの注意点
・実際の取引所の価格データは使わない・シミュレーションなので現実に売買は行わない
・コインチェックが GMO コインよりも値段が高い時にのみアービトラージに挑戦していく(コードを簡略化するため)
・価格差の大きい、小さいは価格の絶対値ではなく過去 15時点との比較で行う(後述)
現実のアービトラージでは、
二つの取引所の価格差が1万円以上ならエントリーして、価格差が完全にゼロになった時に反対売買する
というやり方はあまり上手くありません。なぜならば、
その時のビットコインの価格によっては1万円という絶対的な数字は大き過ぎるかもしれませんし逆に小さ過ぎるかもしれませんからね。
また、そもそも価格差が完全にゼロになるということ自体が、長期間起きないかもしれません。
そこで今回のコードでは、
・二つの取引所の価格差をずっと観察しておき
・今の価格差が過去15個の時点と比べて突出して開いている場合に裁定取引のエントリーを行う
・今の価格差が過去15個の時点と比べて突出して開いている場合に裁定取引のエントリーを行う
ことを想定しています。
具体的には、価格差の開きが偏差値70以上(2σ区間より上)であればエントリーします。
逆に価格差の開きの偏差値が30以下になればポジションを閉じます。
この辺の処理は例によってpandasのデータフレームを使って計算し、行数を減らしてみました。
もし実運用するのであればこの辺の設定は詰めて考える必要があるでしょう。
コード本体
コード本体はこんな感じです。import pandas as pd
import numpy as np
duration=15
sigma=2
samples=1000
#デモ用に各取引所のビットコイン価格時系列データを適当に設定(ここでは正規乱数を使用)
#実際の運用ではリアルタイムにデータを取得していく
coincheck=[1000*np.random.randn() for i in range(samples)]
gmo=[1000*np.random.randn() for i in range(samples)]
#データ処理はpandasでやるとシンプルに書ける
df = pd.DataFrame()
df["coincheck"]=coincheck
df["gmo"]=gmo
df["c-g"]=df["coincheck"]-df["gmo"]
df["c-g_mean"]=df["c-g"].rolling(window=duration).mean()
df["c-g_std"]=df["c-g"].rolling(window=duration).std()
df["c-g_upper_limit"]=df["c-g_mean"]+sigma*df["c-g_std"]
df["c-g_lower_limit"]=df["c-g_mean"]-sigma*df["c-g_std"]
#現在ポジションを取っているか
have_position = False
for i in range(len(df)):
#coincheckがbitflyerよりも価格が高いときのみポジション取得を検討する仕様。簡便さのため。
should_take_potision = df.iloc[i]["c-g"] > df.iloc[i]["c-g_upper_limit"]
should_release_position = df.iloc[i]["c-g"] < df.iloc[i]["c-g_lower_limit"]
if (not have_position) and should_take_potision:
print("coincheckで買い、gmoで売却(ポジション取得)します. 価格差:"+str(df.iloc[i]["c-g"]))
# 実運用では、コインチェックの購入処理(他記事参照)とbitflyerの売却処理を書く必要あり
have_position=True
elif have_position and should_release_position:
print("coincheckで売却、gmoで買い戻し(ポジションを解消)します. 価格差:"+str(df.iloc[i]["c-g"]))
# 実運用ではコインチェックの売却処理とbitflyerの購入処理を書く必要あり
have_position=False
else:
pass
一応、アービトラジっぽいことはできるはずです。
ただし実運用の段階では、取引所の反応に対するエラー処理をかなり頑張って書く必要が出てくるでしょう。
コメントを残す