bitbankのAPIを使ってrubyでBOT自動売買してみた

2018年04月08日

仮想通貨界隈では最近BOTを使った自動取引が流行ってみるみたい。

今年の初め辺りにbitbankで自動取引BOTを作ってたんだけど、APIが謎のエラーを吐いてどうしようも無かったから中断してた。
それが解決したので、3月中旬くらいからBOT作成を再開して、動かしてみてるところ。

■なんでbitbankなのか
界隈ではレバレッジを効かした取引が流行っているけど、これ以上損失を大きくしたくないし、そもそも自動売買初心者だから現物からやりたい。
bitbankは取引手数料が6月まで無料(2018/4/8現在)なので、どれだけ少額で売買しても手数料による損がない。
国内取引所のbitflayerとかzaifとかは手数料が取られたり、注文が通りにくかったりっていう噂が多いから、bitbankにした。

■使用言語
言語はrubyを使うよ。
界隈ではpythonがよく使われてるみたいだけど、python経験ないし、rubyが好きだからね。
APIはbitbank公式の「ruby_bitbankcc」を使うよ。

■APIインストール&使い方
インストールはこれでOK。

$ gem install ruby_bitbankcc

APIの使い方はRubyBitbankccのInstallationを読めば分かる。

基本形は以下。

bbcc = Bitbankcc.new("YOUR API KEY", "YOUR SECRET KEY")
bbcc.read_transactions('btc_jpy')

「read_transactions('btc_jpy')」の部分を呼び出したいAPIによって変えるだけでOK。

■売買戦略
自動売買の知識とかないから、思いつき戦略で行くよ。

・対象通貨はBTC/JPY。
・1回の注文は0.01BTC
・1秒ごとに価格をチェック。
・3分前と比べて、0.3%以上上昇/下落したら、現在の値段で売り/買い注文を入れる。(親注文)
 かつ、3分前の値段で買い/売り注文を準備する。(子注文)
・注文状況を監視して、親注文が約定したら、子注文を入れる。
・10分以内に親注文が約定しなかったら、親注文を取り消す。(子注文も破棄)
・3日以内に子注文が約定しなかったら、子注文を取り消す。

■実装方法
以下のスレッドを用意して、パラレルに動かす。

・価格取得スレッド
 1秒ごとの価格をリストに追加していくだけ。
 価格取得には「api.read_ticker()」を使う。

・注文スレッド
 1秒ごとに価格リストの現在の価格と3分前の価格(正確には60*3個前の価格)を比較して、価格差が0.3%以上なら、現在の資産を確認。
 資産確認には「api.read_balance()」を使う。

 残資産があって注文可能なら、親注文と子注文のインスタンスを生成。
 親注文に子注文を持たせて、親注文を親注文キューに追加。
 その後は一定時間(3分)待機する。(同じような注文を複数作らないようにするため)

・親注文実行スレッド
 0.1秒ごとに親注文キューを監視。(実際にはQueueのpopでスレッド自体が待機する)
 親注文が追加されていたら、親注文を実行して、子注文を子注文キューに追加する。
 注文実行には「api.create_order()」を使う。

・子注文実行スレッド
 0.1秒ごとに子注文キューを監視。(実際にはQueueのpopでスレッド自体が待機する)
 子注文が追加されていたら、親注文のステータスを確認。
 注文確認には「api.read_order()」を使う。

 親注文が約定していたら、子注文を実行。
 親注文が取り消し済みなら、子注文をキューから削除。
 親注文が約定・取り消しされてなければ、子注文をキューに戻す。
 親注文が一定時間(10分)約定しなければ、親注文を取り消す。

・取り消しスレッド
 1時間ごとにアクティブ注文を監視。
 アクティブ注文取得には「api.read_active_orders()」を使う。

 発注から一定時間(3日)経過している注文を取り消す。
 注文取り消しには「api.cancel_order()」を使う。

■ruby_bitbankccを改造
ruby_bitbankccはデフォルトだと設定するnonceが1秒単位なので、1秒より細かい単位API実行が出来ない。
なので、以下のように変更した。

ファイル:bitbankcc.rb

変更前:
nonce = Time.now.to_i.to_s
変更後:
nonce = Time.now.strftime("%Y%m%d%H%M%S%L")

同じ箇所が何ヶ所もあるので、全部同様に置換しておく。
これでミリ秒単位でnonceが設定されるから、より細かい単位でAPI実行が出来る。

API実行は1秒以上間隔を空けなければならないっていうような規約も特に無かった(見当たらなかった)ので、大丈夫だと思う。
というか、1秒間隔だと遅すぎて使い物にならない。

■運用実績
資産状況をちゃんと出力していないから、グラフとかは作れていない。
とりあえず、BTCがどのくらい変化したかだけ見てみると、こんな感じ。

BOT開始前(3/18):
 0.53856192 BTC
現在(4/8 14時):
 0.60934742198 BTC
 (0.42636192BTC + 136,122JPY。単価:743895 BTC/JPY)

BTCで見れば0.06BTCくらい増えた。

この期間ずっと今のアルゴリズムで動いてたわけでもなく、色々エラーで止まってたりした期間もあるから、実際の運用期間は分からない。
それでも少しはBTCが増えたので、悪くない感じ?

ただ、この間にBTC価格が90万円台から70万円台に下がってるから、単純にBTCの量で見ると増えて当然な気がしなくもない。
とは言っても、ちゃんと親注文+子注文が約定してるから、かなり少額だけど利益は出てるんじゃないかな。

■欠点とか改善点とか
・注文発動のトリガーが固定だけど、可変にした方が良いのかも知れない。
 0.3%固定だと、全然注文しない時間帯があったりする。
 逆に値動きが激しいときに0.3%で発動しちゃうと、もっと大きく幅取れたのになーってシーンがあったりする。

・このアルゴリズムはレンジ相場にしか向かないかも。
 上昇トレンドだと、安い価格での買い注文がドンドン溜まっていく。
 下降トレンドだと、高い価格での売り注文がドンドン溜まっていく。
 資産ロックを防ぐ為に一定期間での注文取り消しを実装したけど、親注文だけ約定して子注文を取り消すと、含み損になる。
 上昇/下降トレンド中でもある程度の値動きはあるから、そこで多少利益取れればまぁ良いのかなぁ。

■今後
とりあえずは今のままでもう少し様子を見て、何か良い案が浮かんだら改善していきたい。

■ソース
ソースはあまり綺麗じゃないのと、量が多いので載せるのはやめておくよ。
希望があれば載せるかも。


bitbankのAPIでエラーコード「20001」が出るときの対処法

2018年04月08日

bitbankのプライベートAPIで何故かエラーコード「20001」が出て一向に使えない問題で大分悩んだので、その解決法を載せておくよ。

まず、公式に問い合わせてみた回答がこちら。

当該エラーレスポンスに関しては、原因は以下のいずれかとなります。

1.署名生成処理に誤りがある

2.APIドキュメント(https://docs.bitbank.cc) 「署名作成」の項をご確認下さい。

3.GitHubリポジトリ(https://github.com/bitbankinc) にて、いくつかの言語にてSDKを公開しておりますので、ご参考にして頂けますでしょうか。

4.nonceが以前送信した値より若い

5.nonce値は、必ず前回のリクエスト時の値より大きな値をご指定下さい。

6.APIキーを画面から削除している

7.APIキーの文字列が誤っている

8.APIのアクセス権限が不足している(API登録時に「参照」「取引」「出金」をお選び頂けます)

なるほど。
どれも当てはまらない。

ってことで、APIキーを再生成してみた。

すると…、
プライベートAPIが使えるようになった!

今までの苦労は何だったのか。
結局原因は分からず。

■結論
APIのプライベートAPIでエラーコード「20001」が出たら、とりあえずAPIキーを作り直して再チャレンジすると良い。

以上。


小田原城で花見

2018年03月31日

かまぼこ食べに行こうぜ!って誘われたので、小田原城まで行ってきた。

小田原城址公園でかまぼこ祭りをやってて、出店が出てたり、ステージでちょっとしたイベントをやってたりした。
あげかま美味しかった。

その後は、小田原城の周りの桜をみながら散策。
小田原城は小学生時代以来かな?
花見に来たのは初めてだったけど、予想以上に桜が綺麗でとても良かった。
天気も快晴だし陽気も文句なし。
花粉さえ飛んでいなければね。


NIKON D500, 35mm(52mm), 1/1000sec, f/7.1, ISO100
小田原城と桜。


NIKON D500, 48mm(72mm), 1/640sec, f/7.1, ISO100
縦構図でも悪くない。


NIKON D500, 35mm(52mm), 1/800sec, f/7.1, ISO100
別地点から。
真っ白な城壁が綺麗。


NIKON D500, 28mm(42mm), 1/640sec, f/7.1, ISO100
構図に迷う。


NIKON D500, 25mm(37mm), 1/640sec, f/7.1, ISO100
天守閣の入り口は行列ができてた。


NIKON D500, 105mm(157mm), 1/640sec, f/5.6, ISO100
桜の後ろに天守閣のボケ。


NIKON D500, 18mm(27mm), 1/320sec, f/7.1, ISO100
桜の裏から。
こういう角度も悪くないよね。


NIKON D500, 25mm(37mm), 1/320sec, f/7.1, ISO100
天気も良くなかなかの盛況。


NIKON D500, 18mm(27mm), 1/320sec, f/7.1, ISO100
あおりの小田原城と桜。


NIKON D500, 25mm(37mm), 1/250sec, f/7.1, ISO100
城が無くても十分。


NIKON D500, 35mm(52mm), 1/500sec, f/7.1, ISO100
広場は花見客。


NIKON D500, 66mm(99mm), 1/500sec, f/7.1, ISO100
堀の外から天守閣。


NIKON D500, 32mm(48mm), 1/640sec, f/7.1, ISO100
堀に沿って植えられた桜。
後ろのマンションがちょっと残念。


NIKON D500, 30mm(45mm), 1/400sec, f/7.1, ISO100
垂れ下がるほどの立派な桜。


NIKON D500, 24mm(36mm), 1/400sec, f/7.1, ISO100
水辺に桜も良い組み合わせ。


NIKON D500, 22mm(33mm), 1/500sec, f/7.1, ISO100
ちょっと角度を変えるとまた違った感じになる。


NIKON D500, 105mm(157mm), 1/500sec, f/7.1, ISO100
圧縮してみる。


NIKON D500, 105mm(157mm), 1/500sec, f/7.1, ISO100
桜アーチ。


NIKON D500, 62mm(93mm), 1/400sec, f/7.1, ISO100
手前に桜を入れると遠近感が出て良い構図。


新宿御苑の寒桜とかヒヨドリとか

2018年03月11日

新宿御苑でちょっと早いお花見的なお散歩に行ってきた。

梅の木はそんなに無かったかな。
寒桜は見頃の修善寺寒桜っていうのが綺麗だった。

鳥は、ヒヨドリ、シジュウカラ、名前の分からない鳥。

久々に歩いたら疲れた。
運動不足感半端ない。
以下写真。
時間が無いのでコメントはなしで。


NIKON D500, 300mm(450mm), 1/2000sec, f/4.0, ISO100


NIKON D500, 300mm(450mm), 1/500sec, f/4.0, ISO100


NIKON D500, 300mm(450mm), 1/1600sec, f/4.0, ISO100


NIKON D500, 300mm(450mm), 1/800sec, f/4.0, ISO100


NIKON D500, 300mm(450mm), 1/1000sec, f/4.0, ISO100


NIKON D500, 300mm(450mm), 1/500sec, f/4.0, ISO200


NIKON D500, 300mm(450mm), 1/500sec, f/4.0, ISO140


NIKON D500, 90mm(135mm), 1/400sec, f/7.1, ISO100


NIKON D500, 105mm(157mm), 1/320sec, f/5.6, ISO100


NIKON D500, 48mm(72mm), 1/400sec, f/7.1, ISO100


NIKON D500, 105mm(157mm), 1/400sec, f/7.1, ISO100


NIKON D500, 50mm(75mm), 1/200sec, f/7.1, ISO100


NIKON D500, 34mm(51mm), 1/250sec, f/7.1, ISO100


NIKON D500, 58mm(87mm), 1/250sec, f/7.1, ISO100


NIKON D500, 300mm(450mm), 1/500sec, f/4.0, ISO180


NIKON D500, 300mm(450mm), 1/2000sec, f/4.0, ISO100


NIKON D500, 300mm(450mm), 1/640sec, f/4.0, ISO100


NIKON D500, 300mm(450mm), 1/500sec, f/4.0, ISO640


NIKON D500, 300mm(450mm), 1/500sec, f/4.0, ISO720


さくらVPSのUbuntuでufwが効かない問題

2018年02月18日

さくらVPSはiptalbesにデフォルトの設定が入っていて、それが影響してufwが効かないらしい。

iptablesを無効にすると良いらしい。

1.iptableの設定ファイルiptables.rulesを削除(ファイル移動)
#mv /etc/iptables/iptables.rules /var/tmp

2.iptablesが起動時設定されるのを解除(ファイル移動)
#mv /etc/network/if-pre-up.d/iptables /var/tmp

3.再起動
#reboot

OSインストール時にufwを有効にするスタートアップスクリプトがさくらの公式から配布されてるので、これからUbuntuをインストールするなら、スタートアップスクリプトを使うのが確実かも。
さくらのVPS、スタートアップスクリプト「Ubuntu ufw」を更新しました

(参考)
さくらのvpsのubuntuでufwが有効にならない