[API]ビットコインスキャルピングの自動売買システムの作り方(Poloniex)
公開日:
:
APIの仮想通貨自動売買 ビットコイン, 仮想通貨, 自動売買, スキャルピング
目次/もくじ
「アービトラージあるからいいじゃん」ってずっと思ってたのですが、(今でも思ってる)スキャルピングに関する問い合わせが止まらないので、一応作り方を解説します。(PHP)
この記事にピンポイントで飛んでくる方が多いみたいなので一応先に言っておくと、ビットコインのAPI処理については過去記事を読んできた方を対象としています。この記事だけをいきなり読んで開発できるということはないと思うので、適宜過去記事を参照してください。
コインチェックのAPIの使い方[PHP] 仮想通貨の自動売買開発
アービトラージと比較すると、取引所はどこか1社で良いので、プログラミングは楽です。問題は如何にして過去レートを引っ張ってくるかということになります。
仮想通貨ビットコイン取引できるEAもOKな海外FX会社一覧(MT4/MT5)
これまでにもチラッと言及した記憶があるのですが、基本的には日本の仮想通貨取引所は過去レート/ヒストリーデータを引っ張ってくることはできません。そのため、海外の仮想通貨取引所を使うことになりますが、海外の取引所のベース通貨は米ドルのため、ドルで条件付けを行います。
例によってPOLONIEXを使うので、POLONIEXのAPIについてはこれまでの記事を参照してください。
POLONIEXのAPIでビットコインのヒストリデータを取得するやり方
POLONIEXのAPIではUNIXタイムスタンプを使う
MT4/MT5などと違いPOLONIEXのAPIでは過去レートの取得に際して、UNIXタイムスタンプを使います。
UNIXタイムスタンプで指定しているのだから1秒ごとにデータを記録していてくれても良いのですが、リクエストするときにはある程度の時間幅を持たせてあげます。
1 2 3 4 5 6 7 8 9 10 |
FUNCTION GetHistoryRate($unixtime) { $Url = "https://poloniex.com/public?command=returnTradeHistory¤cyPair=USDT_BTC&start=".$unixtime."&end=".($unixtime+30); $file = file_get_contents($Url); $file = mb_convert_encoding($file, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); $HistoryRate = json_decode($file,true); return($HistoryRate[0]["rate"]); } |
おそらくですが、これはヒストリカルデータの保存方式に由来するものだと考えられます。
秒や分単位による時間ベースではなく、レートが変化したタイミングで更新情報を逐次保存しているため、このようなリクエストになっていると思います。
上の例では安全のため30秒の幅を持たせていますが、もっとシビアにしたい場合は時間幅を狭くしてください。ただし、あまり狭くし過ぎるとレートが返ってこなくなります。
さて、
現在レートは上の関数で現在時刻のタイムスタンプを引数に渡せば取得できるので、これである一定時間前のレートと現在レートが取得できます。
信用取引 x スキャルピング
スキャルピングをするということは、現物取引ではなく信用取引ということなので、信用取引用のエントリーの関数と決済の関数を用意します。(現物取引でスキャもできないことはないですが、ちょっと意味合いが変わってくると思います。)
例:コインチェック
ZAIF,bitFlyerは過去記事を見てください。
エントリー関数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
FUNCTION TradeCC($ordertype,$orderrate) { global $orderamount; global $AccessKey_c; global $AccessSecret_c; $orderpair = "btc_jpy"; if( $ordertype == "buy" ) { $ordertype = "leverage_buy"; $arrQuery_c = array("amount" => $orderamount, "order_type" => $ordertype, "pair" => $orderpair,); } else if( $ordertype == "sell" ) { $ordertype = "leverage_sell"; $arrQuery_c = array("amount" => $orderamount, "order_type" => $ordertype, "pair" => $orderpair,); } $URL_c = "https://coincheck.com/api/exchange/orders"; $intNonce_c = round(microtime(true) * 1000);//time(true); $Body_c = http_build_query($arrQuery_c); $Message_c = $intNonce_c . $URL_c . $Body_c; $Signature_c = hash_hmac("sha256", $Message_c, $AccessSecret_c); $curl_c = curl_init(); curl_setopt($curl_c,CURLOPT_RETURNTRANSFER,true); $options_c = array( CURLOPT_HTTPHEADER => array( "ACCESS-KEY: $AccessKey_c\r\n". "ACCESS-NONCE: $intNonce_c\r\n". "ACCESS-SIGNATURE: $Signature_c", ), CURLOPT_POST => true, CURLOPT_BODY => $Body_c ); curl_setopt($curl_c, CURLOPT_URL, $URL_c); curl_setopt($curl_c, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($curl_c, CURLOPT_POSTFIELDS, $Body_c); curl_setopt_array($curl_c, $options_c); $res_c = curl_exec($curl_c); curl_close($curl_c); $res_c = "CoinCheck:".$res_c; return $res_c; } |
決済処理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
FUNCTION ExitCC($orderid,$ordertype,$orderamount) { global $AccessKey_c; global $AccessSecret_c; $orderpair = "btc_jpy"; if( $ordertype == "buy" ) { $ordertype = "close_long"; $arrQuery_c = array("amount" => $orderamount, "order_type" => $ordertype, "position_id" => $orderid, "pair" => $orderpair,); } else if( $ordertype == "sell" ) { $ordertype = "close_short"; $arrQuery_c = array("amount" => $orderamount, "order_type" => $ordertype, "position_id" => $orderid, "pair" => $orderpair,); } $URL_c = "https://coincheck.com/api/exchange/orders"; $intNonce_c = round(microtime(true) * 1000); $Body_c = http_build_query($arrQuery_c); $Message_c = $intNonce_c . $URL_c . $Body_c; $Signature_c = hash_hmac("sha256", $Message_c, $AccessSecret_c); $curl_c = curl_init(); curl_setopt($curl_c,CURLOPT_RETURNTRANSFER,true); $options_c = array( CURLOPT_HTTPHEADER => array( "ACCESS-KEY: $AccessKey_c\r\n". "ACCESS-NONCE: $intNonce_c\r\n". "ACCESS-SIGNATURE: $Signature_c", ), CURLOPT_POST => true, CURLOPT_BODY => $Body_c ); curl_setopt($curl_c, CURLOPT_URL, $URL_c); curl_setopt($curl_c, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($curl_c, CURLOPT_POSTFIELDS, $Body_c); curl_setopt_array($curl_c, $options_c); $res_c = curl_exec($curl_c); curl_close($curl_c); return $res_c; } |
決済処理をするためには現在の建玉のIDを参照する関数を先に呼び出しておく必要があります。
決済に必要なポジションの情報は取引所によって異なるので、それぞれの取引所APIのドキュメントの決済処理を一応参照してください。
ポジション情報の取得は一覧ででるのですが、めんどくさいので、
1ポジションしかとらないという希望的観測の元、適当な関数を作ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
FUNCTION GetCurrentPositionIDCC() { global $AccessKey_c; global $AccessSecret_c; $URL_c = "https://coincheck.com/api/exchange/leverage/positions"; $intNonce_c = round(microtime(true) * 1000);//time(); $arrQuery_c = array("status" => "open"); $Body_c = http_build_query($arrQuery_b); $Message_c = $intNonce_c . $URL_c . $Body_c; $Signature_c = hash_hmac("sha256", $Message_c, $AccessSecret_c); $curl_c = curl_init(); curl_setopt($curl_c,CURLOPT_RETURNTRANSFER,true); $options_c = array( CURLOPT_HTTPHEADER => array( "ACCESS-KEY: $AccessKey_c\r\n". "ACCESS-NONCE: $intNonce_c\r\n". "ACCESS-SIGNATURE: $Signature_c", ), CURLOPT_GET => true, CURLOPT_BODY => $Body_c ); curl_setopt($curl_c, CURLOPT_URL, $URL_c); curl_setopt($curl_c, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($curl_c, CURLOPT_GETFIELDS, $arrQuery_c); curl_setopt_array($curl_c, $options_c); $res_c = curl_exec($curl_c); curl_close($curl_c); return $res_c; } |
少し戻って、エントリー関数の引数にオーダーレートの指定がありますが、
念のためpublicAPIでレートを取得して渡してもいいですし、
成行注文の場合はそもそも関係ないので適当な数字を入れてもOKです。
あとのエントリーの条件文ですが、ドルベースなので、
ドルの値幅の間隔になれていない日本人はそのまま比較しない方が賢明です。
つまり、
(現在のビットコイン価格($))ー (一定時間前のビットコイン価格($)) > 100ドル
とするよりも
(現在のビットコイン価格($)) / (一定時間前のビットコイン価格($)) > 1%
とパーセンテージで比較した方が良いと思います。
これなら1ビットコインが10万円でも100万円でも対応できます。
決済条件については、かんたんのため固定SL/TPで勘弁してください。
1 2 |
//あらかじめ変数にいろいろ代入して if( $currentrate > $lastentryrate + $pips_tp ) |
こんな感じです。
建玉情報は
1 |
$PositionData_cc = json_decode(GetCurrentPositionIDCC(),true); |
こんな感じで取れば、
1 2 3 4 5 |
echo "<br>建玉タイプ ".$PositionData_cc["data"][0]["new_order"]["side"]; echo "<br>建玉状況 ".$PositionData_cc["data"][0]["status"]; echo "<br>建玉ID ".$PositionData_cc["data"][0]["new_order"]["id"]; echo "<br>建玉量 ".$PositionData_cc["data"][0]["amount"]; echo "<br>約定価格 ".$PositionData_cc["data"][0]["open_rate"]; |
このように連想配列で取得できます。
あとはお好きなようにこれらの関数を使って平文に条件文を書けばOKです。
基本的な構成はMQLと同じにした方が良いと思います。
ひとつ注意して欲しいのは、
ZAIFはサーバーが不安定なので、サーバーダウンや取引停止やアクセス一時停止が頻発しています。
bitFlyerは決済処理が反対売買なのですが、オーダー送信後にその約定が反映されないことがあるので、
決済しようとしてもポジション情報が取得できないことがあります。
(問い合わせて確認済みです。取引所も不具合として認めています。)
まぁ、スキャルピングするならMT4/MT5のCFDチャートでもいいような気はしますけどね。
ちなみに、
そもそも論ですが、ビットコイン単体でスキャルピングをするよりも、アルトコインを含めた”順張りイナゴ型スキャルピング”の方が現時点では戦略的に優位だと思います。
ただ、アルトコインはAPIで処理できないので、”お金を増やす”というシンプルな目標に対して最適解をとるのであれば、今は自動化には目をつぶった方が良いと思います。
もちろん、これまでに紹介したように、IEオブジェクトを使ったマクロで自動化することも不可能ではありませんけどね。(いろいろ、めんどうじゃん)
ビットコインスキャルピングを自動売買でやってみた感想
FXがまだ下火でブームが訪れる前、急な値動きに対して順張りでスキャルピングすることで10万円を億にできる時代がありました。
今はレート操作や何やかんやあってできないのですが、
ビットコインで同じようなことができないか検証してみました。
ロジックはシンプルで、「x秒前よりもレートがy%動いたら順張りエントリー」という手法です。
もちろんAPIで自動売買です。
正確に記録したわけではないのですが、
「60秒前よりもレートが1%動いたら」の場合、
ほとんどエントリーが発生せず、トレードチャンスがありませんでした。
「600秒前よりもレートが1%動いたら」の場合、
エントリーは一日に数回発生しましたが、あまり利益は取れません。
「600秒前よりもレートが1.5%動いたら」の場合、
エントリーは上記と同じで、利益はトントンといった感じです。
FXだったら数値最適化処理をして、最適な組み合わせをバックテストから導き出すことができるのですが、
ビットコインは実際にやってみて試すしかないので、
正直なところ….
飽きてしまいました。
「今のところはアービトラージで利益が取れるから、スキャルピングまでしなくてもいいんじゃない?」
というのが正直な感想です。
ただし、アービトラージはあまり大きなロットでできないですが、スキャルピングの場合はロットが大きくても論理上耐えそうな気はするので、資金が大きい場合は検証を重ねるのもありなんじゃないかと思います。
日本の取引所の場合は過去レートを引っ張ってこれないので、POLOを使ったのですが、
結果が微妙になったのはそのせいもあるかもしれません。
少し調べてみたところ、国内の取引所でも第三者のサービスを経由することにより
過去レートが取得可能なようです。
それができれば、ビットコインのメタトレーダー的なものを作るのも面白いかもしれませんね。
サーバー上で稼働するタイプの自動売買システムをローカルPCで稼働させる方法
これまで開発したビットコインの自動売買では、
ローカルPC -> PHPサーバー -> 取引所サーバー
という経由をしていました。
これは複数の人が使う場合には汎用性がありますが、個人で使う場合はベストとは言えません。
今回は、ローカルPCでPHPが動くようにして、経由するサーバーの数を減らし、速度と安定性を上げます。
今回の方法は、
PHPが動くローカルPC -> 取引所サーバー
でやるので、通信速度が上がり、自サーバーへの負荷などの問題がなくなります。
やり方はかんたんで、
XAMPPを使います。
XAMPPとは、かんたんに自サーバーを立てられるソフトで、
Apache、DB、PHP
がかんたんに動作するようになります。
その反面、セキュリティ上は問題があり、
実際にXAMPPでサーバーを立てている人はほとんどいないと思います。
便利さとセキュリティはトレードオフですね。
https://www.apachefriends.org/index.html
XAMPPをインストールするとCドライブの直下にXAMPPフォルダが生成されます。
そのなかにhtdocsというフォルダがあるので、
そこにPHPファイルを投げ込めばOKです。
XAMPPの起動画面はこんな感じです。
「Start」ボタンを押せばPHPが動きます。
あとは適当なブラウザを開いて、
https://localhost/
と入力すれば、
htdocs直下のindex.phpが開きます。
画像では各取引所の現在のレートを取得しています。
ローカルPCから直接取引所に送信しているので高速です。
また、自サーバーがアクセス拒否やサーバーダウンや503エラーなどを吐き出すリスクも排除できます。
関連記事
-
ZAIFのAPIの使い方[PHP]
APIを使ってbitFlyerからレートを取得したり、残高を確認したり、オーダーを出す方法まとめです
-
APIビットコインアービトラージシステム
ここまで業者間アービトラージシステムのプログラミングの考察?をしてきましたが、 中には「中身がどう
-
コインチェックのAPIの使い方[PHP]
公開:2017/6/21 PHPプログラマと言っても、いろいろな分野の人がいるわけで、WEB系だか
-
bitFlyerのAPIの使い方と注意事項
APIを使ってbitFlyerからレートを取得したり、残高を確認したり、オーダーを出す方法まとめです
-
仮想通貨の自動売買API開発 使用言語と方向性
公開:2017/6/21 今ならAPIの仕様の改良により、 CoinCheck、ZAIF、bit