何年か前に仮想通貨取引が流行っていたけど、当時は興味もなくYouTubeに表示される仮想通貨の広告が鬱陶しいし、投資なのか投機なのかもよくわからないしギャンブル?程度の認識だったので特に調べることもしていなかった。そんな訳でネット上で話題になっても、特に深追いすることなく過ごしてきたのだけど、今さらに同僚から仮想通貨の自動取引は面白いよ、とプレゼンされたので、少しだけ遊んでみることにした。
ざっと調べてみたところ取引自動化には欠かせないのが取引所が公開しているAPI。取引に必要なデータをAPIで取得してPCやサーバで処理して注文処理するという処理を自動化する。そこで、今回はAPIが使える取引所のひとつBitbankの口座を開設した。当初資金の10万円を入金したのが2018年末。
年末年始の空いた時間を使って、まずは仮想通貨の値動きと取引ロジックを考えた。
数日相場を数日観察してみると1時間で数%が値動きすることもあれば、反面まったく値動きしない時間帯もある。これでは適当に買ったり売ったりしたらあっという間に資金がなくなってしまう。株式などと異なり24時間365日の取引が前提になるので、人の手でPCやスマートフォンを使って取引するようなものではなさそう。
自動取引とAPI
取引自動化の基本はAPIを使う。そこでまずはBitbankのAPIドキュメントとGithubのサンプルコードを眺めてみる。 ドキュメントの量はそれほど多くないというより、思ったよりあっさりしている。これだけ?って印象を受けるが、複数言語に対応したライブラリも提供されていたり、サンプルコードもアップされていたりと、普通に取り引きをするのであれば過不足はなさそう。
ざっくり言えば、
1)PCにプログラミング言語とBitbankが提供するライブラリをクライアントにインストール
2)Bitbankが提供するAPIを叩いて必要な情報を取得
3)クライアントで取引条件を指定して「買い」、「売り」注文のAPIを叩く
というシンプルな仕様。RESTful APIの利用経験があるなら数時間で概要は理解できるはず。
利用した言語
Bitbankからは取引に必要なライブラリがnode.js Java Python Rubyで提供されている。それぞれの言語でできることに違いはないので、好きな言語を選べばいい。どれを選ぶか悩んだけど今回はBitbankのサンプルコードがPythonで書かれていたPythonを選択した。
コインを選ぶ
Bitbankにはいくつかのコインの売買ができる。この辺は好みだと思うけど、日本円で売買でき、かつ取引量が多いコインを選んだ方が自動取引はしやすい気がする。値動きが少ないコインだとコンピュータを使った自動売買のメリットが活かせないというのもある。いくつかのコインで試してみたけど値動があること、取引量がそれなりに多いことからXRPというコインを選んだ。
目的
自動取引を開始する目的は以下の通り。あくまでも少額資金での自動取引の検証という前提。
・仮想通貨の自動取引で利益を出すことが現実的に可能なのか
・人の手は一切使わないで、取引の全てを自動化する
目標
入金した資金を100倍、200倍にするような想定はないが、何も目標を立てないとロジックの作りようもないので、2019年中に入金した資金の2倍にあたる20万円にすることを目標にした。いらぬ心配かもしれないけど、あまり利益を出しすぎると税金の手続きも必要になることも考慮しなければならないので、このくらいの目標がちょうどいいという判断。いちにちあたりにすると10万円÷365日≒274円の利益を上げ続ければ達成できるという試算で。
開発環境
Pythonの開発環境は手元にあるMac、Windows PCでも構築できるけど、今回はクラウドベースのエディタ、AWS Cloud 9を利用する。AWSのアカウントさえあれば数分で環境を作れるし、デフォルトでPythonも使える。開発環境を整える煩雑さもないし、ブラウザさえ使えれば場所と時間、デバイスを選ばず同じ環境でコードが書ける。
Cloud 9はAWSが提供するサービスなので時間当たりの費用は掛かるけど、毎月90時間起動しても200円程度と無視できる範囲。参考までに、実際にコードを書いた時間は20時間程度だったので、AWSからは数十円の請求で済んだ。
取引ロジック
ここが最も頭を悩ませたところ。仮想通貨は株と同じく安く買って高く売り、その利ザヤを利益とするのが基本的な取引方法。信用取引やレバレッジを掛けたりできる取引所もあるようだけど、口座開設したBitbankは現物取引だけを取り扱っている。仮想通貨に現物もなにも無いような気がするが、それは言葉の問題でとにかく入金した日本円で仮想通貨を安く購入し、高く売るというのが大前提。
ロジックを検討するための前提としてコンピュータが得意なことを考える
・人間の手ではできないような高速な計算と処理、
・人間と違って絶対にサボらない・ミスらない定期的な処理、
・無感情、無関心
逆にコンピュータにできないことは、
・急な相場の変化に対応
・未来を予測して売買する
といったところか。可能な限りこの特徴をを活かすような処理を考える。過去のデータからの機械学習も検討したけど結局のところ上がるか下がるかで言えば確率は50%に近づくはずなので、あまり意味がなさそう。
高速な処理、つまり1分間に数百回、数千回の取引をすることはプログラム上は可能。有無をいわせず高速でスクリプトを回し続ければいいだけ。 ただ実際にクライアント側で高速でスクリプトを回せたとしても、サーバ側のAPIが処理に追いつかないことや、オーダー可能な注文数が30個以内に限られること、などの制限から早々に現実的ではないことに気が付く。頑張っても60回/分の取引が限界に近いという感触。
次に検討したのは定期的な処理。一時間に一度、一分間に一度など一定時間で売買処理を繰り返す。これであれば、サーバへの負荷も少なく、オーダー数も厳密に管理する必要もなくなる。まずはは高速処理よりも定期的な処理を採用した方が現実的だと考えた。
とは言えこちらは仮想通貨どころか相場、投資の素人。なにか取っ掛かりはないものかと、仮想通貨、自動取引でざっと検索してみるが、残念なことに情報商材とかアフェリエイトスパムみたいなノイズ情報ばかりで、ほとんど役に立たない。取引ツールを数万~数十万円で販売しているのもよくヒットしたけど、他人の書いたツールを使うのは気持ち悪いしいずれ嵌め込まれるだけだろう。
仮想通貨の自動取引でインターネット上からヒントを得るのは難しそうなので、株式の取引ロジックを取り入れることを検討した。株取引の方が仮想通貨より歴史も長くノウハウも豊富なせいか、ネット上にも参考になる情報は多い印象。
いくつか仮想通貨の自動取引に採用できそうな取引方法があったけど、今回はその中でもドルコスト平均法を採用してみることにした。
Wikipediaより。 ドル・コスト平均法(英: dollar cost averaging)とは、
株式や投資信託などの金融商品の投資手法の一つ。定額購入法ともいう。金融商品を購入する場合、一度に購入せず、資金を分割して均等額ずつ定期的に継続して投資する。例えば「予定資金を12分割して、月末ごとに資金の1/12を投入し、一年かけて全量を買う」という手法。 高値掴みのリスクを避けるための時間分散の一種であるが、数量を等分するのではなく、金額を等分する点が単なる分散と異なる。価格が高い時は購入数量が少なく、安い時には多いため、単純な数量分割に比べ平均値の点で有利になるとされる。価格が下がった場合のみならず、上がったときにも買う点で難平買いとは異なる。 長期投資でリスクを抑制し、安定した収益を得たい場合に使われる手法である。上げ相場でドル・コスト平均法を行うと平均購入単価がかえって高くなり、収益を減少させてしまう欠点もある。タイミングを精密に測れないため、値動きの早い商品で、ハイリターンを目指す投資には向かない。
株式では毎月決まった日に一定額を購入するのが基本。ただしこのまま採用しても値動きの激しい仮想通貨ではリスクが高すぎるし、そもそも月に一度ならAPIなど利用せず手作業で十分だろう。
そこで、毎月ではなく時間を短縮して購入間隔を1分間に設定し、ある程度利益が出た時点で売るというロジックにしてみる。これであれば、大勝はできないけど大負けもなさそう。急激な価格の変動にも影響を受けにくいはず。購入するのは一定「数量」ではなく一定「額」というのがポイント。1回あたりの購入金額は結構悩んだけど最終的に100円/分とした。
毎分100円を買い、投資前の総資産から200円上がったら全て売り、という処理を永遠に繰り返す。一回当たりの購入金額に根拠が見つけられなかったけど、投資金額10万円の1%という切りのいい数字にしておけば後から計算がしやすいかなといった割と雑な理由。つまり1~2回/日売り注文が確定すれば、目標金額の274円/日の利益は確保できるという試算。
リスクはないとはいえ、それなりの値動きはあるので、急落に備えて「損切」もロジックに入れておく。一定額以上総資産が下がったら売りを入れるというのは自動取引を成立させるのには絶対に必要になるはずだ。
取引のフロー
上記ロジックをコードに書いた。
1.APIが正常であることを確認する
2.現在の資産が前回取引から+200円以上であれば全量売り注文を入れ、20%以上含み損が出れば損切り
3.日本円残高を確認し100円以下であれば以降の処理を中止する
4.仮想通貨の現在値を取得する
5.100円を現在値で割って購入数量を算出する
6.注文数量が30個溜まっていたら最も古い注文をキャンセルする
7.5で算出した数量の買い注文を入れる
8.取引履歴をデータベースに記録する
困ったのはBitbankにはテスト環境やデモ環境がないこと。そのため自分でテストコードを書くか、本番環境でテストするしかない。さすがにテスト用のコードを書くのは怠すぎるので、危険を承知で本番環境でテストする。テストをする度に数円から数十円の資金が減ったり増えたりするのがアレだけど仕方ない。
数週間資金を増やしたり減らしたりしながらテストして、ようやくそれなりに動くようになったのが2019年の1月中旬くらいだった。
本番環境
極端な話、取引の環境は手元のPCでも構築できるけど、当然24時間PCを稼働していなければならない。さすがに24時間365日自宅のPCを起動しておくには、管理の面で面倒なので、クラウドサーバを使っての構築を検討した。
当初は手軽にAWSのEC2がいいかなと思ったけど、やはり気になるのは費用面。一番安価なEC2インスタンスを借りたとしても、数千円/月の費用が発生してしまう。10万円しか原資がない中で、確実に毎月数千円の費用が発生してしまうとサーバ費用だけで、赤字になってしまう可能性が高い。無料で使えそうなHerokuとか格安VPSも考えたけど、費用を抑えると今度は運用時の制限が厳しくなってしまう。
そこで最近勉強し始めたAWS Lambdaで動かしてみることにした。LambdaはEC2のように固定の月額費用は発生せず、課金の対象はコードを実行した時間と回数分だけ。なおLambdaには無料枠があるため、その範囲で使えば費用が発生することはない。
Lambda無料枠
月間 1,000,000 件のリクエスト 月間 400,000 GB-秒
Lamdaはインフラの管理もサーバの管理も不要。管理自体は全部AWSの中の人がよろしくやってくれるので、書いたコードをアップロードすれば動き出す。いくつかの言語をサポートしていて、Python含まれるので、開発環境で使ったコードをほぼそのまま流用できた Cloud 9で書いたコードをLambdaへdeployするのもほんの数クリックするだけで、AWSが上手いことやってくれるので、Cloud 9を使ったのはローカルPCで開発するより結果的に効率的だった。
デメリットというか、Lambdaの仕組み上データの永続化はできないので、別途データベースは用意する必要はある。そこを踏まえて今回は以下の構成にした。
Cloud Watch > Lambda > DynamoDB
1.Cloud Watchで1分に1度Lambdaをキック
2.LambdaでBitbank APIへのアクセスと取引処理
3.取引した売買データはDynamoDBに保存
Cloud WatchとDynamoDBもAWSがサービスとして提供していて、Lambda同様、LinuxやWindowsサーバなどを立てる必要はない。ある程度利用すると料金が発生するけど、どちらも余裕すぎる無料枠。
実際、4月のAWSのlambdaとDynamoDBの利用量は以下の通りだった。かなり無茶しても無料枠を超えることはなさそう。
Lambda
DynamoDB
100日経過後の資産額
取引履歴は一時間に一度Twitterに自動Tweetした。Bitbankのアプリで資産を見てもいいけど、頻繁に見たとしても手作業で売買できないし、途中から面倒になってきたのでたまにTwitterを見てたまに確認するだけにした。 全てのTweetは公開しているので、取引の推移は誰でも見ることができる。
最初のTweet
評価資産: 116325円
— XRP_BOT (@bot_xrp) 2019年2月4日
含み益: -17.0円
数量: 348.12XRP
購入単価: 32.733円
現在単価: 32.685円
利益:16325円 #XRP #リップル
この記事を書いた時のTweet
評価資産: 141234円
— XRP_BOT (@bot_xrp) 2019年5月18日
含み益: 2.0円
数量: 30.170XRP
購入単価: 43.114円
現在単価: 43.182円
利益:41234円 #XRP #リップル
結果は以下の通り。
総資産:141,200円
取引回数:約12万回
一日当たりの平均利益額:412円
AWS利用料:0円
利益:41,200円
グラフ
資産額の単位は日本円で、途中数値が減っているのはバグを修正したのと、XRPの送金を試して遊んでしまったから。
2019年の1-3月のチャートは基本的には下げ相場だったけど、順調に資産は増えていき、100日で約4万円(40%)程度の利益が出ている。
その日の値動きが大きいと利益が出やすく逆に小さな値動きだと利益が出にくいロジックなことがわかる。このまま上手いこと自動取引が動いてくれれば、年末には目標値の10万円という利益は達成できそうな見込み。倍々ゲームなので、10年後には1億円超が見えてくるかも(笑)
気が付いたこと、注意すべきこと
レイテンシ
あまり気にしすぎることはないけど、取引所のAPIとクライアントのレイテンシが大きいと注文を入れるまでの時間が増えるため、注文が通りにくくなる可能性も考慮しておく。試しにAPIまでのレイテンシを計測してみると自宅からAPIエンドポイントまでの到達時間が40-200ms、AWS Lambdaからだと6ms以内だった。BitbankのAPIはAWS内にあるようなので、同じRegionにあるLambdaを利用すれば、応答速度が速くなるのではないかと思う。
セキュリティ
APIキーが漏れると第三者に簡単にアクセスされてしまうのでキーはLambdaの環境変数に記述してプログラムにはハードコーディングしない。 同様にGitHubなどのリポジトリにコードを上げる際も注意することくらいか。
損切り
念のため、日本円が底をつきかつ総資産が前回売り注文後から20%減ったら損切りするという処理を入れておいたが、結局1度も発動しなかったので、損切ポイントをより厳密にすれば資金の回転は良くなったのかもしれない。
AWS費用
EC2仮想サーバの月額費用は少し高いような気がするけど、今回のようにサービス系のみを組み合わせて使えばほぼ無料枠の範囲で収まると思う。おそらく無料枠を使い切るような設計にするには、複数の取引所を開設してそれぞれの口座に数千万円単位で入れなければ届かないような感触。
データベースへの記録
取引所のAPIから取得できるデータと取引に使うデータを考慮する必要がある。取引所から取得できるデータと重複して保存しても費用が嵩むだけなので、ある程度割り切って記録した方がいい。
購入金額を動的にする
ドルコスト平均法は一定額を購入し続ける手法だけど、ある程度資金が増えてきたら一回に購入する金額と、売り注文を入れるときの金額は増やした方が資金の回りは良くなる。今回は当初資金が10万円だったので一度の購入額を100円としたけど、15万円になったら150円、20万円を超えたら200円などと持っている資金によって変化させるとより利益がでやすくなるはず。
取引手数料を考慮する
Bitbankは今年の1月4日まで売買手数料が無料で取引できたが、5日以降は手数料が発生するようになった。この辺は上手く計算しておかないと、マイナスになる可能性もある。手数料の体系はコロコロ変わるような感じなので、全自動とはいえ取引所からのお知らせメールくらいはチェックしておく必要はある。
見ない、触らない
コンピュータで取引する利点のひとつに感情が入り込まないというのがある。日々チャートを見たり、経過を見たりすると「もう少し上がるかも、もっと下がるかも」みないに余計なことを考えてしまい、スクリプトを止めたり、手作業で売買したりする可能性がある。そのためエラーが起きないことを確認出来たらチャートは見ない、アプリは触らない、BitobankのWebサイトにログインしないというのは重要。人の手を介在した瞬間に負けるのは自明なので。
まとめ
結果として目標以上の利益は出たけど、100日間という短期間なのででたまたま運が良かっただけなのかもしれないし、完璧な勝ちパターンを手に入れた可能性も否定できない。ただ言えるのは手作業でチャート分析したり、ファンダメンタルズ分析するようなことを時間や労力を掛けて実行するよりは、放置しておくだけなので楽だし精神的にも気楽だ。もう少し長い時間検証して増えていくようであれば資金を増やして億万長者を目指してみようかな。