前回の記事では、CCXTライブラリを使ってBitflyerの最終取引価格を取得し、それに基づいて「買い注文」をpythonのプログラムから出す方法を説明しました。
今回はその続きです。
送信した注文が約定したかどうかをチェックしたり、未約定の注文をキャンセルする方法を解説します。
事前準備
今回の説明にあたり、複数の注文があった方がいいので、前回作ったプログラムを使って3つほど注文を出してみましょう。pythonプログラムを3回実行するだけです。
以下のように、3つの注文が置かれました。
まずはこの注文情報をpythonのプログラムで取得してみましょう。
注文情報を取得する
サーバーに送ったもののまだ約定していない注文のことを(Open Order)といいます。この未約定の注文は、「fetch_open_orders()」という共通の関数で取得できます。
エディタに以下のコードを記述してください。
import ccxt from pprint import pprint bitflyer = ccxt.bitflyer() bitflyer.apiKey = '**********' bitflyer.secret = '**********' orders = bitflyer.fetch_open_orders( symbol = "BTC/JPY", params = { "product_code" : "FX_BTC_JPY" }) pprint( orders )
これを実行すると、以下のような結果が取得できます。
前回までの記事を読んでいれば、特に目新しいことはないと思うので、コードの解説は省略します。paramsに「FX_BTC_JPY」を指定するのを忘れないようにしてください。
実行結果
先ほど出した未約定の注文が3つとも取得できているのが確認できます。fetch_open_orders()で取得した注文情報には、以下の情報が含まれます。
・注文ID(例:JRF20180317-022611-288893)
・注文した日時
・指値の価格
・Buy/Sellの方向
・未約定の残高
注文をキャンセルする場合には、「注文ID」を使います。ここでは、シンプルに「注文ID」だけを表示したいので、以下のようにコードを修正しましょう。
import ccxt from pprint import pprint bitflyer = ccxt.bitflyer() bitflyer.apiKey = '**********' bitflyer.secret = '**********' orders = bitflyer.fetch_open_orders( symbol = "BTC/JPY", params = { "product_code" : "FX_BTC_JPY" }) for o in orders: pprint( o["id"] )
変更したのは最後の「for文」のところだけですね。
コードの解説
上記のfor文は、CryptowatchのAPIを取得する練習記事で解説したのと全く同じパターンです。
JSON形式の構造が[ {},{},{}… ] になっていることと、{}の中身が「 id : 注文ID 」になっていることを把握できれば、同じやり方でデータを取り出せます。詳しくは「API編」の記事を参考にしてください。
プログラミング未経験者の方にとって、for文は慣れるまで少しコツが必要です。最低限、for文/if文/while文だけは知らないと自動売買BOTが作れません。これらの構文を全く知らない方は、以下の記事を読んでおいてください。
最低限必要なプログラミング構文(for文/if文/while文)
実行結果
上記のコードを実行すると、以下のように注文IDだけを取得することができました。
応用:すべての注文を取得する
先ほど書いたpythonプログラムの fetch_open_orders()の部分を、fetch_orders()に変更すれば、すべての注文(約定した注文/未約定の注文)をまとめて取得できます。
何も指定しなければ直近100件のすべての注文が取得されますが、「count」というパラメーターを付ければ取得する件数を調整することができます。
また取得した注文情報の「status」を調べれば、約定したかどうかがわかります。「status : open」のままであれば未約定ですし、「status : closed」になっていれば約定しています。
これを応用して、直近10件の注文が約定しているかどうかを調べるコードを書いてみましょう。以下のようになります。
▽ 直近10件の注文と、その約定の有無を調べるコード例
import ccxt from pprint import pprint bitflyer = ccxt.bitflyer() bitflyer.apiKey = '**********' bitflyer.secret = '**********' orders = bitflyer.fetch_orders( symbol = "BTC/JPY", params = { "product_code" : "FX_BTC_JPY", "count" : 10}) for o in orders: print( o["id"] + " : 注文状況 " + o["status"] )
コードの解説
print()の関数は、print( 変数 + 変数 )で2つの変数の中身を繋いで表示することができます。見やすく表示するために、間に文字を入れたければ、print( 変数 + “好きな文字” + 変数 ) で、間に空白や文字を入れることができます。
実行結果
上記のコードを実行すると以下のように表示されます。
さて、次はこの注文IDをもとにして、注文をキャンセルしてみましょう。
注文をキャンセルする
注文をキャンセルする場合は、cancel_order()という共通の関数を使います。注文IDがすでにわかっている場合は、以下のように書くだけでOKです。
bitflyer.cancel_order( symbol = "BTC/JPY", id = "JRF20180316-172859-799705", params = { "product_code" : "FX_BTC_JPY" })
注) id=””の部分に注文IDを入れてください。
またキャンセルの関数は、orders ではなく order なので間違えないようにしてください。
Bitflyerでは、注文をキャンセルした際に、サーバーからは何のデータも返ってきません。なのでキャンセルできたかどうかを確認したければ、もう1度、fetch_orders()を実行する必要があります。
上記のコードを実行した後、もう1度、fetch_orders()を実行してみましょう。
実行結果
cancelで指定した注文が消えていますね。
管理画面でも確認してみましょう。
無事、注文が無くなっています。
応用:一番新しい注文を取得してキャンセルする
せっかくなので、手動で注文IDを指定するのではなく、fetch_open_orders()で取得した注文をそのままプログラムでキャンセルしてみましょう。今回は応用として「注文のうち一番新しいもの」を自動的にキャンセルします。
Bitflyerから fetch_open_orders() で取得した注文は、以下のように古い順番に並んでいます。
[{注文1},{注文2},{注文3},….]
この配列の最後の要素(一番新しい注文)を指定したければ、orders[-1]と指定すればOKです。コードを書いてみましょう。
import ccxt from pprint import pprint bitflyer = ccxt.bitflyer() bitflyer.apiKey = '**********' bitflyer.secret = '**********' orders = bitflyer.fetch_open_orders( symbol = "BTC/JPY", params = { "product_code" : "FX_BTC_JPY"}) bitflyer.cancel_order( symbol = "BTC/JPY", id = orders[-1]["id"], #11行目 params = { "product_code" : "FX_BTC_JPY" })
コードの解説
今まで学習したことの組み合わせなのでわかると思いますが、6行目の fetch_open_orders() で未約定の注文を取得して、cancel_order() で注文をキャンセルしています。
11行目の id = orders[-1][“id”] で、取得した未約定の注文のうち、一番後ろの注文(一番最新の注文)の注文IDを指定しています。
実行結果
実行してもう1度、注文状況を取得してみましょう。
無事、新しい方の注文が消えましたね。
管理画面でも確認しておきましょう。
新しい方の注文がキャンセルされています。
以上が、Bitflyerにpythonで出した注文の状況を管理して、注文IDを取得し、未約定の注文をキャンセルする方法でした。
練習問題
未約定の注文の一覧を取得して、それらを「すべて」一括でキャンセルするプログラムを書いてみましょう。ヒントとしては、最初の「注文IDだけを表示する」のプログラムコードを修正して、for文の中に注文キャンセルのコードを入れるとうまくいきます。
いつも参考にさせていただいています。
注文の取得ですが、ストップ注文のような特殊注文は取得できないようなのですが、どうしたらストップ注文等の未約定注文も取得できるのでしょうか?
いつも参考にさせていただいています。掲載されているやり方ではストップ注文などの特殊注文の取得が出来ないのですが、どのようにしたらいいのでしょうか?
こちらのサイトでプログラミングを勉強し始めてとてもわかりやすく参考になっています。ありがとうございます。
質問なんですが、注文情報を取得するのところで打ち込んでも帰ってくるのが[]で何が起きているのかわからず、コピペしてみても同様の結果です。なんのエラーなんでしょうか?
こんばんは、先日コメントした内容なのですが
orders = bitflyer.fetch_open_orders(
symbol = “BTC/JPY”,
params = { “product_code” : “FX_BTC_JPY” })
を
orders = bitflyer.fetch_open_orders(‘FX_BTC_JPY’)
に変えることで動作することができたので一応報告します。
記事ありがとうございます。
product_codeが’BTC_JPY’でないと動作しないようです。
下記にbitflyerのAPIの仕様が記述されているので、動作しない場合は仕様変更の可能性があるので下記の仕様を参考にしたら解決する可能性があります。
https://lightning.bitflyer.com/docs#%E6%B3%A8%E6%96%87%E3%81%AE%E4%B8%80%E8%A6%A7%E3%82%92%E5%8F%96%E5%BE%97
たこさんと同じところでハマりました。
ccxt1.39.52アップデートでsymbol = ‘FX_BTC_JPY’じゃないと取得できなくなったようです。
orders = bitflyer.fetch_open_orders(
symbol = “FX_BTC_JPY”,
params = { “product_code” : “FX_BTC_JPY” })
symbolを直せば取得できます
初めてプログラミングに取り組んでみていますが、大変勉強になっております。
注文状況を取得するプログラムを実行しても結果は[ ] と表示されるだけでした。
以下で同じ状況の人がいたので、ccxtの更新とコードの修正もしてみましたがうまくいきませんでした。
https://teratail.com/questions/302881
もっと調べていじってみます。
お世話になっております。
みなさんがはまっている[]だけが返ってくる問題ですが、
ツイッターで解決策を見つけてつぶやいてくださっている方がおられました。
symbol = “BTC/JPY:JPY”,
とするとよいそうです。私もこれで解決しました。
大変参考にさせていただいております。
既に何名かの方が報告されていますが、bitflyer.fetch_open_ordersがやはり上手く処理できなかったので、以下参考とした記事のURLを共有させていただきます。
https://note.com/minaul/n/nbe5bfc7f706d
.hasで確認すると、flyerのorders系は現状ほぼfalseのため、ccxt経由で直接API叩いて加工する他ないのかなと。。