さて、前々回の記事ではBitflyerのAPIを使って買い注文を出す方法を紹介しました。このとき注文を出すだけでも結構長いコードを書かなければならなかったのを覚えているでしょうか?
CCXTライブラリを使えば、これを1行で書くことができます。実際にやってみましょう!
事前準備
bitFlyer lightning の最低注文単位は0.01BTCからです。
現在(2018年4月)のレートでいうと9000円くらいですね。そのため、口座には最低1万円以上の資金が必要です。
今回はレバレッジ無しで最低単位の注文をします。一応テストなので、約定しないように注意しながら、現在価格から10%以上離れた場所に指値を入れます。そして、それをキャンセルするところまでプログラムしてみます。
bitFlyerのアカウント登録がまだの方は、ぜひこちらから登録してください。
(追記) 2018年4月から最低注文単位が0.01BTCに引き上げられました。この記事はそれ以前に作成したものなので、画像が0.001BTCのままになっています。文字部分は修正しています。
現在のBTC-FX価格を取得する
前々回の記事では、BTC-FXの画面にログインして目視で価格を確認しました。ですが、今回はより本格的に、価格を調べるところもすべてPythonのプログラムでやりましょう。
エディタを起動して以下のように記載してください。
import ccxt from pprint import pprint bitflyer = ccxt.bitflyer() ticker = bitflyer.fetch_ticker('BTC/JPY', params = { "product_code" : "FX_BTC_JPY" }) pprint(ticker)
コードの解説
1行目と2行目でccxtライブラリとpprintライブラリをimportします。これは前回の記事と同じですね。pprintライブラリは配列を綺麗に表示するために使います。
3行目の「bitflyer = ccxt.bitflyer()」は、ビットフライヤーで関数を使うために必ず最初に書かなければならないコードです。準備のようなものだと思ってください。
4行目でティッカー情報を取得しています。すでに学んだように、ティッカー情報の取得はパブリックAPIなので、この時点ではAPIキーやシークレットは必要ありません。Bitflyerの場合は、FXでは「product_code」を「FX_BTC_JPY」に指定するのを忘れないようにしてください。
5行目のpprint()で、取得した ticker を黒い画面に表示しています。
実行結果
それでは、上記のコードをpythonファイルで保存して、Anacondaプロンプトで実行してみましょう。以下のように表示されました。
{'ask': 902954.0, 'average': None, 'baseVolume': 274827.01507782, 'bid': 902900.0, 'change': None, 'close': None, 'datetime': '2018-03-16T00:13:01.147Z', 'first': None, 'high': None, 'info': {'best_ask': 902954.0, 'best_ask_size': 0.2, 'best_bid': 902900.0, 'best_bid_size': 1.2837385, 'ltp': 903111.0, 'product_code': 'FX_BTC_JPY', 'tick_id': 14952020, 'timestamp': '2018-03-16T00:13:01.147', 'total_ask_depth': 7224.20363872, 'total_bid_depth': 5425.62384916, 'volume': 306014.57114597, 'volume_by_product': 274827.01507782}, 'last': 903111.0, 'low': None, 'open': None, 'percentage': None, 'quoteVolume': None, 'symbol': 'BTC/JPY', 'timestamp': 1521159181147, 'vwap': None}
この中で、最終取引価格(=現在価格)だけ知りたければ、「last」の部分を見ればOKです。この記事の執筆時点では、903111円(90万3111円)ですね。
あるいは、bid(買い板の中の最高価格)を見てもいいです。売買BOTのアルゴリズムで買いシグナルが出た場合、指値注文を入れるのであれば、この「bid」か「last」のどちらかの価格で指値を入れることが多いと思います。
なお、この取得したJSONデータから最終取引価格(last)だけ取り出したければ、先ほどのpythonのプログラムの5行目を以下のように書けばOKです。
pprint( ticker["last"] )
これは「JSON形式のデータから欲しい数字だけを取り出そう!」の復習なので、わからない方はこちらを読んでください。
FXの証拠金残高を確認する
次にポジション管理のために、FXの証拠金残高などを取得してみましょう。エディタに以下のコードを書いてください。
import ccxt from pprint import pprint bitflyer = ccxt.bitflyer() bitflyer.apiKey = '**********' bitflyer.secret = '**********' collateral = bitflyer.private_get_getcollateral() pprint( collateral )
コードの解説
今回はプライベートAPIを使うので、APIキーとAPIシークレットを準備する必要があります。4行目・5行目の’**********’の部分に各自のAPIキー・シークレットをそれぞれ入力してください。
またCCXTライブラリには、Bitflyerで BTC-FX の証拠金残高を取得する共通の関数がありません。そのため、ここではBitflyerの「v1/me/getcollateral」というAPIを使っています。(collateralは英語で「担保」という意味です)。
このようにCCXTライブラリでは、共通のメソッドが見つからない場合に、各取引所で個別に提供されているAPIを、直接使うこともできます。具体的な方法については、以下の記事で紹介しています。他の場面でも困ったら参考にしてみてください。
・Bitflyerや各取引所の個別のAPIをCCXT経由で利用する方法
実行結果
上記のコードをAnacondaプロンプトで実行してみましょう。以下のような結果が表示されます。
{ "collateral": 100000, "open_position_pnl": -715, "require_collateral": 19857, "keep_rate": 5.000 }
上から順番に、
・預入証拠金の評価額(collateral)
・ポジションの評価損益(open_position_pnl)
・現在の必要証拠金(require_collateral)
・現在の証拠金維持率(keep_rate)
です。
自動売買BOTでは、証拠金の残高から取得可能なポジションのサイズを自動計算させて、可変ロットで注文を出すこともできます。この方法は第7回の「資金管理編」で詳しく解説するので楽しみにしていてください。
初心者の方は、まずは固定ロット(0.1BTCなど)でちゃんと売買できるようになりましょう!
買い注文を出す
今回はテストなので、最終取引価格が90万円のところ、10%以上離して80万円で買い指値を入れてみます。数量は最低単位の0.01BTCにします。
注文には、「create_order()」というCCXTの共通の関数を使います。エディタを起動して以下のコードを書いてください。
import ccxt from pprint import pprint bitflyer = ccxt.bitflyer() bitflyer.apiKey = '**********' bitflyer.secret = '**********' order = bitflyer.create_order( symbol = 'BTC/JPY', type='limit', side='buy', price='800000', amount='0.01', params = { "product_code" : "FX_BTC_JPY" }) pprint( order )
これで終わりです!
実際に注文を送るために書いたのは、order = bitflyer.create_order() の1行だけです! 見やすいように改行してるだけなので、「1行じゃねぇじゃねーか!」とか言わないでください><
コードの解説
CCXTには指値注文、成行注文を出すための関数、買い注文・売り注文を出すための関数もありますが、上記のように、create_order()で詳細を指定すれば、全パターンの注文を出せますので、この1つだけ書き方を覚えたほうが簡単です。
以下だけ覚えてください。
symbol=””の部分 ⇒ 通貨ペア
type=”” の部分 ⇒ limitが指値/marketが成行
side=”” の部分 ⇒ buyが買い/sellが売り
price=”” の部分 ⇒ 指値を入れる場合の価格
amount=””の部分 ⇒ 注文数量
params={} の部分 ⇒ 各取引所のAPIに渡せるパラメーター
Bitflyerでは、「product_code」を「FX_BTC_JPY」に指定するのを忘れないようにしてください。これを忘れると現物注文になります。
6行目で、Bitflyerのサーバーに注文を出すと、サーバーから注文IDが返ってきます。この注文IDは、今後、注文状況を確認したりキャンセルするときに使います。そのため、返ってきた値は、orderという変数で受け取り、それをpprint()で画面に表示しています。
実行結果
それでは、上記のコードをpythonファイルで保存して、Anacondaプロンプトで実行してみましょう。以下のように表示されれば成功です。
実際にBitflyerのFX画面でも、注文が通っていることが確認できます。
今回の記事はここまでです。
次回の記事では、注文状況を確認したり、まだ約定していない注文をキャンセルする方法を解説していきます!
tyotaさん、いつも勉強させていただきありがとうございます。
一箇所誤植?と思われる部分がありましたので、コメントさせていただきます。
>>
bitflyer = ccxt.bitflyer()
bitflyer.apiKey = ‘**********’
bitflyer.secret = ‘**********’
の部分は、このまま実行すると
ccxt.base.errors.AuthenticationError: requires `apiKey’
というエラーが出てしまいます。
そこで、他のサイト等を参考に
bitflyer = ccxt.bitflyer({
‘apikey’: ‘*************’,
‘secret’: ‘*************’
})
と変更して、apiキーとシークレットを渡してやることで上手くいきました。
出力結果が
{‘collateral’: ‘0.000000000000’,
‘keep_rate’: ‘0.0’,
‘margin_call_amount’: ‘0.0’,
‘margin_call_due_date’: None,
‘open_position_pnl’: ‘0.0’,
‘require_collateral’: ‘0.0’}
となるのはFXBTCのAPI取り扱い終了だからでしょうか
私も写経をしていて上記の方と同じエラーが出て困ってました。
私の場合はapiKeyのKが小文字のkになっていただけでした
(;^ω^)
初心者あるあるですね
リョータさん
有益な情報を丁寧に解説頂きありがとうございます。
多少Pythonでのトレードの勉強を本などで行っていますが、知らないことが多く勉強になっています。
一点、今日写経してエラーになった内容を報告します。
(エラー修正しなくても次に進めるので解決法の探索をスキップしましたが。。。)
『現在のBTC-FX価格を取得する』内にある以下のコード部でエラーが発生しています。
ccxtやBitflyerのAPIなどをざっと調べましたが、
prodct_codeやalias(素性がよくわかりません)あたりが関係してそうです
・対象のコード(恐らくこの個所)
ticker = bitflyer.fetch_ticker(‘BTC/JPY’, params = { “product_code” : “FX_BTC_JPY” })
pprint(ticker)
・エラーメッセージ(Jupyter notebook環境)
AttributeError Traceback (most recent call last)
Input In [28], in
1 #現在のBTC-FX価格を取得する
2 #bitflyer.fetch_tickerで価格取得
4 bitflyer = ccxt.bitflyer()
—-> 5 ticker = bitflyer.fetch_ticker(‘BTC/JPY’, params = {“product_code”: “FX_BTC_JPY”, “market_type”: “FX”})
6 pprint(ticker)
File c:\users\….(途中削除)\env\lib\site-packages\ccxt\bitflyer.py:328, in bitflyer.fetch_ticker(self, symbol, params)
327 def fetch_ticker(self, symbol, params={}):
–> 328 self.load_markets()
329 market = self.market(symbol)
330 request = {
331 ‘product_code’: market[‘id’],
332 }
File c:\users\….(途中削除)\env\lib\site-packages\ccxt\base\exchange.py:1517, in Exchange.load_markets(self, reload, params)
1515 if self.has[‘fetchCurrencies’] is True:
1516 currencies = self.fetch_currencies()
-> 1517 markets = self.fetch_markets(params)
1518 return self.set_markets(markets, currencies)
File c:\users\…(途中削除)\env\lib\site-packages\ccxt\bitflyer.py:183, in bitflyer.fetch_markets(self, params)
181 elif future:
182 alias = self.safe_string(market, ‘alias’)
–> 183 splitAlias = alias.split(‘_’)
184 currencyIds = self.safe_string(splitAlias, 0)
185 baseId = currencyIds[0:-3]
AttributeError: ‘NoneType’ object has no attribute ‘split’