Bitflyerや各取引所の個別APIをCCXTライブラリ経由で直接利用する方法

CCXTライブラリでは、どの取引所でも共通で使える関数が用意されています。

例えば、create_order()という注文を出すための関数は、Bitflyerだけでなく、Coincheck、Zaif、Bitmexなどでも共通で使えます。これはCCXTが各取引所ごとのAPIの仕様の違いを、見えない裏側で処理してまとめてくれているからです。

・参考:CCXTが便利な理由

しかし一方で、各取引所にしか存在しない独自のAPIを使いたい場合は、CCXTの共通の関数ではカバーされていない場合があります。

例:Bitflyerの特殊注文

例えば、ご存知のように、Bitflyerでは「特殊注文」ができます。これは、例えば、100万円の買い注文と同時に条件付で110万円の売り注文を出すIFD注文や、110万円の利確注文と90万円の損切注文を同時に出し、どちらか1つが通ればもう片方を自動的にキャンセルするOCO注文などです。

しかしこれらの特殊注文は、CCXTの共通の関数からは出すことができないため、BitflyerのAPIを直接使う必要があります。

各取引所のAPIを直接使う方法

最初にまず結論からいいます。
CCXTでは、基本的に取引所のすべてのAPIが「明示されない関数」として内部で実装されています。すべての取引所のAPIは、以下のようなルールで関数を作れば、CCXT経由でも使用することができます。

例)BitflyerのAPI
APIの種類 : プライベートAPI
APIのメソッド : GET方式
APIのパス : /v1/me/getcollateral

例)CCXTの内部で実装されている関数名

bitflyer.private_get_getcollateral()

つまり各取引所のAPIをCCXT経由で直接使いたい場合は、以下の3つの情報を調べればいいことになります。この3つの情報がわかれば、以下のルールで関数名を組み立てられます。

X)プライベートAPIかパブリックAPIか?
Y)メソッドはGET方式か?POST方式か?
Z)APIのリクエストURL(パス)は?

関数名 : .X_Y_Z()

例えば、今回の例であげたBitflyerのFXの証拠金や維持率を取得するためのAPI(v1/me/getcollateral)の場合、公式ドキュメントを調べれば、以下のように記載されています。


・BitflyerAPIドキュメント

個人アカウントの残高を取得するAPIが、プライベートAPIなのは明らかなので、上記のドキュメントから「.private_get_getcollateral()」が使えるんだろうな、とアタリをつけることができます。(/v1/me/ の部分は無視して構いません)

なお、どのようなパラメーターを渡すことができるか(または、どのようなパラメーターが必須か?)は、各取引所のAPIドキュメントで調べる必要があります。

プログラム初心者向けの流れ

何かやりたいことがある場合、まずはそれがCCXTの共通の関数で対応できないかを調べます。前の記事でも説明しましたが、各取引所がどのような共通の関数に対応しているかは、「.has」で調べることができます。

▽ 取引所で対応している共通関数を調べるためのコード


import ccxt

bitflyer = ccxt.bitflyer()
method_list = bitflyer.has

for key,value in method_list.items() :
	if value == True:
		print( key )


これを実行してみると、Bitflyerでは以下の共通の関数に対応していることがわかります。

共通の関数一覧

cancelOrder()
createOrder()
createMarketOrder()
createLimitOrder()
fetchBalance()
fetchL2OrderBook()
fetchMarkets()
fetchOrder()
fetchOrderBook()
fetchOrders()
fetchTicker()
fetchTrades()
withdraw()

もしこれらの関数で、やりたいことができなさそうであれば、上記の方法を使って Bitflyer のAPIを直接利用することを検討します。

なお、今回説明した内容はすべてCCXTの公式マニュアルに記載されています。プログラムのAPI仕様書や英語を読むことが苦手でない方は、そちらを読んだ方がいいと思います。公式マニュアルは以下です。

・CCXT公式マニュアル

Bitflyerの未約定の全注文をCCXTで一括でキャンセルする方法

前回の記事「CCXTでBitflyerに出した注文を管理・キャンセルする方法」の最後の練習問題の解答です。

解答


import ccxt

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:
	bitflyer.cancel_order(
		symbol = "BTC/JPY",
		id = o["id"],
		params = { "product_code" : "FX_BTC_JPY" })


fetch_open_orders()で未約定のすべての注文を取得し、それをfor文を使って1つずつキャンセルしていきます。キャンセルする注文IDを id = o[“id”] と指定するのが、今回のポイントでした。なお、Bitflyerの場合は、product_codeを指定するのを忘れないようにしてください。

(for文の解説)

orders[0][“id”]
orders[1][“id”]
orders[2][“id”]
orders[3][“id”]
orders[4][“id”]



の順番で処理したい要素がある場合は、for o in orders : と書くことで、orders[?]までの部分を o という変数に入れて順番に処理することができます。このとき、orders[?][“id”]は、for文の中では、o[“id”]で指定できます。

CCXTでBitflyerに出した注文を管理・キャンセルする方法

前回の記事では、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文の中に注文キャンセルのコードを入れるとうまくいきます。

正解はこちら

CCXTライブラリでBitflyerに注文を出す方法をマスターする

さて、前々回の記事では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は英語で「担保」という意味です)。

BitflyerのAPIドキュメント

このように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画面でも、注文が通っていることが確認できます。

今回の記事はここまでです。
次回の記事では、注文状況を確認したり、まだ約定していない注文をキャンセルする方法を解説していきます!

CCXTが便利な理由!CCXTライブラリをインストールしよう

前回の記事では、BitflyerのAPIを使って実際にBTC-FXの買い注文を出す方法を解説しました。

少し長い記事だったので、疲れた方も多いかもしれませんね(笑)。でもキチンと読んでくださった方は、いきなりライブラリの利用からから入る方よりも、間違いなく「本質的な部分」の理解が深まっているはずなので自信を持ってください!

さて、今回からはCCXTという外部のライブラリを使って、全く同じ「bitFlyerに買い注文を出す」コードを、もっと簡単に実装する方法を紹介します。

CCXTライブラリのgithubページ

なぜCCXTライブラリを使うのか?

1つ目の理由は、自分で長いコードを書かなくて済むからです。

前回の記事では、「sendchildorder」というBitflyerのAPIを利用して、pythonプログラムからBitflyerのサーバーに注文を出すことができました。しかし実際には、このAPIを利用するためには、以下のような手順を踏まなければなりませんでした。

1)現在時刻のタイムスタンプを作る
2)注文価格や数量などのパラーメータを設定する
3)パラメーターをJSON形式に変換する
4)メッセージ認証コード(暗号署名)を作る
5)通信用のヘッダーを作成する
6)リクエストを送る

このうち実質的に(2)の部分以外は、すべてのAPIリクエストで共通の処理です。なので毎回、自分で書かなくても、自動的に実行してくれたら楽ですよね。

例えば、買い注文を出す場合には、「指値か/成行か」「買いか/売りか」「注文ロット数は?」「指値の価格は?」といった随時、変更したい部分だけを指定し、それ以外の部分は1つの関数にまとめておいて、いつでも呼び出せるようにしておけば、プログラムを書くのが遥かに楽になります。

これをやってくれるのがライブラリです。

取引所ごとのAPIの違いを気にしなくていい!

2つ目の理由は、取引所ごとのAPIの仕様の違いを無くすためです。

APIというのは、各取引所が独自に開発しているものなので、取引所によって仕様が違います。例えば、bitFlyerでは「sendchildorder」というAPIで注文を出しましたが、Zaifの場合は「trade」というAPIを使いますし、bitbankであれば、「order」というAPIを使います。

通信に含めるパラメーターのルールも、取引所ごとに違います。例えば、Bitflyerは「size」で注文ロット数を指定しますが、Zaifは「amount」で注文ロット数を指定しなければなりません。

このような取引所ごとのAPIの違いを気にしながら、自動売買BOTを作るのはかなり面倒です。

1つの売買ロジックを複数の取引所で試したい場合でも、取引所ごとにpythonコードを書き直さなければなりません。また、裁定取引のように取引所間の価格差を利用した売買BOTを作りたい場合、取引所ごとに注文の方法が違うと非常に厄介です。

CCXTライブラリで出来ること

CCXTなどのライブラリは、このような「各取引所ごとのAPIによる注文の違い」を、見えない裏側でまとめて処理してくれます。そのため、先頭の1行目でCCXTライブラリを読み込めば、あとはすべての取引所で共通の関数を使うことができます。

例えば、以下のような関数(メソッド)がすべての取引所で「共通」で使えます。

create_order() ・・・ 注文を出す(成行/指値)
cancel_order() ・・・ 注文をキャンセルする
fetch_ticker() ・・・ ティッカー情報を取得
fetch_balance() ・・・ 口座残高を取得
fetch_order_book() ・・・ 板情報の取得

また各取引所ごとのAPIをCCXTライブラリを経由して直接使うこともできます。例えば、bitFlyerにしか存在しないAPIを使いたい場合は、上記の共通のメソッドを使わずに、直接、BitflyerのAPIを利用することもできます。

詳しい使い方は今後の記事で説明していきます!

CCXTをインストールしよう

まずはCCXTライブラリをPythonにインストールしていきましょう。Anacondaプロンプトを起動して以下の1行を打ち込むだけです。

pip install ccxt

すると以下のようにインストールが開始されます。

「Successfully installed … 」と出て、また文字が打てる状態になれば、インストールは完了です。

Bitflyerで出来ることを確認しておく

早速、CCXTライブラリを使ってpythonプログラムを1つ書いてみましょう。今回は、BitFlyerでできることを把握するために、対応している共通の関数(メソッド)の一覧を確認してみます。

エディタを起動して以下のコードを書いてみてください。

import ccxt
from pprint import pprint

bitflyer = ccxt.bitflyer()
pprint( bitflyer.has )

コードの解説

最初の「import ccxt」は、CCXTライブラリを利用するための1文です。これは今後、CCXTを使うときには必ず記述します。

2行目の「from pprint import pprint」は、pprint()を使ってデータを綺麗に表示するためにインポートしてみました。今までの記事では、すべてprint()だけで表示していましたが、改行がないと見にくいデータは、pprint()で表示した方が綺麗です。

3行目の「bitflyer = ccxt.bitflyer()」も、Bitflyerの取引所を使う場合には最初に必ず書かなければならないコードです。準備のようなものだと思ってください。

4行目の「bitflyer.has」は、CCXTライブラリにあるBitflyerのプログラムが、どの共通関数に対応しているかを確認するためのコードです。これをpprint()を使って黒い画面に表示しています。

実行結果

それでは実行してみましょう!
以下のように表示されました。

「True」と記載されているものは、Bitflyerでも使えます。
以下のような共通関数は使えるということですね。

cancelOrder() ・・・ 注文をキャンセルする関数
createOrder() ・・・ 注文を出す(買い/売り、指値/成行)関数
fetchBalance() ・・・ 残高を確認する関数
fetchTickers() ・・・ ティッカー情報を取得
fetchOrderBook() ・・・ 板情報を取得

一方、見てのとおり、結構、使えない(Flaseになっている)関数もあります。

前回の記事の意味

前回の記事を読んでくださった方ならわかると思いますが、CCXTライブラリは結局のところ、各取引所のAPIを裏側で叩いているだけのものが多いです。そのため、各取引所が該当するAPIを提供してくれていなければ使えません。

また上記の共通メソッドにはパラメーターを渡すこともできますが、どのようなパラメーターを渡すことができるかは、各取引所のAPIの仕様によって異なります。例えば、Bitflyerで BTC-FX のデータを取得するためには、”FX_BTC_JPY”というパラメーターを渡さなければなりません。渡さないとBTC現物のデータが返ってきます。

このようなルールも、裏で各取引所のAPIが動いていることを知っていなければ、なかなか自分で気づいたり調べることが難しいと思います。そのため、前回の記事ではわざわざ1度、APIだけで注文を出す方法を学びました。

さて、次の記事では、CCXTライブラリを使って、実際に「BitflyerFXの現在価格と口座の残高を取得して、購入額と数量を決め、買い注文を出す」という多くの売買BOTで必要にな一連の流れをまとめて勉強します!

(追記)

※ 最新版 Anaconda3.7 ではCCXTのインストールができず、3.6にダウングレードするとできたという報告があるようです。もし出来ない方は参考にしてください。

bifFlyerのAPI経由でPythonで「買い注文」を出してみよう

さあ! ようやくここまで来ました!
いよいよPythonでプログラムを書いて、実際にBitflyerに注文を出してみましょう! まずはシンプルに「買い」の注文を出してみることにします。

今回はあくまでテストなので、成約しないように、最低単位のBTCを指値で注文します。注文後は、いったん自分で手動で注文をキャンセルしてください。

(bitFlyerのアカウント登録がまだの方は、ぜひこちらから登録してください)

事前準備(必要な口座残高)

bitFlyer lightning の最低注文単位は0.01BTCからです。
現在(2018年4月)のレートでいうと1万円くらいですね。

bitFlyerFXで注文するための必要証拠金は、レバレッジの倍率によって違います。例えば、レバレッジ2倍で100万円分(=約1BTC)のポジションを取るには、最低50万円の残高が必要です。一方、レバレッジ10倍であれば、最低10万円の残高が必要です。

ちなみに追証ラインは80%、ロスカットライン(証拠金維持率)は50%です。レバレッジ2倍の例だと、90万円を切った時点で追証がかかり、75万円を切ると強制決済されます。レバレッジ10倍の場合だと、98万円を切った時点で追証がかかり、95万円を切ると強制決済されます。

Bitflyerの必要証拠金について
Bitflyerのロスカット(証拠金維持率)について

この記事では0.01BTCの注文しか出しませんので、残高は数万円もあれば十分です。

(追記) 2018年4月から最低注文単位が0.01BTCに引き上げられました。この記事はそれ以前に作成したものなので、文字部分は修正していますが、一部の画像が0.001BTCのままになっています。

bitFlyerの買い注文のAPI

bitFlyer(FX)の買い注文のAPIは以下のような形式になります。

https://api.bitflyer.jp/v1/me/sendchildorder

今まで勉強したパブリックAPIに似ていますね。ただしこちらのURLは今までのようにブラウザで見ることはできません。

理由は「POSTメソッドという通信方式で送らないといけないから」ですが、意味がわからなくても構いません。単に、何となく以下のようなパラメーターをボディに含めて送る方式だと理解してください。

必要なパラメーター

1)product_code
取引する通貨種類のこと。現物なら「BTC_JPY」。今回はFXなので「FX_BTC_JPY」

2)child_order_type
指値注文か成行注文か、という意味。今回は指値注文なので「LIMIT」と入れる。

3)side
買い(ロング)か売り(ショート)か。今回は買いエントリーするので「BUY」と入れる。

4)price
指値注文を入れる場合には、価格の指定が必須になる。今回は練習なので、bitFlyerFXの管理画面にログインして現在価格を確認して、そこから10~20%乖離した価格(間違って成約しない価格)を入れる。

5)size
注文数量(ロット数)。今回は、最低単位の0.01BTCだけ買いたいので、「0.01」を入れる。

他にも設定できるパラメーターはありますが、今回、指定する必須のパラメーターはこれだけです。

なお、どのようなパラーメーターを設定できるのかは、BitflyerのAPI仕様書を見ればわかります。前の記事でも言いましたが、なるべく自分でAPI仕様書を読むことに対して、抵抗感が無くなるようにしておきましょう。

買い注文のAPI仕様書(公式ドキュメント)

買い注文の価格について

もう少しレベルの高い自動売買BOTだと、指値の注文価格は当然、自動で設定します。例えば、API経由で現在の板情報を取得して、買い板の中で一番高い価格(買い気配値)を設定することが多いです。すでに当ブログでAPIの使い方を学んでくださった方は、大雑把なやり方のイメージは付くと思います。

ですが今回の記事では、BTC-FXの管理画面にログインして、自分の目で現在価格を確かめ、少し離したところに指値を入れることにします。この記事の執筆時点では、最終取引価格が90万500円なので、今回は10%以上離して、80万円に買い指値を入れてみます。

具体的なPythonコード

あまり前置きが長くなっても良くないので、いったん具体的なソースコードを全部見ておきましょう。少し長くなりますが、怖がらないで、まずはザっと意味を想像しながら、読んでみてください。


import hashlib
import hmac
import requests
import datetime
import json


api_key = "APIキーを入力"
api_secret = "APIシークレットを入力"

base_url = "https://api.bitflyer.jp"
path_url = "/v1/me/sendchildorder"
method = "POST"

timestamp = str(datetime.datetime.today())

param = {
	"product_code" : "FX_BTC_JPY",
	"child_order_type" : "LIMIT",
	"side" : "BUY",
	"price" : 指値価格を入力,
	"size" : 0.01,
}
body = json.dumps(param)

message = timestamp + method + path_url + body
signature = hmac.new(bytearray(api_secret.encode('utf-8')), message.encode('utf-8') , digestmod = hashlib.sha256 ).hexdigest()

headers = {
	'ACCESS-KEY' : api_key,
	'ACCESS-TIMESTAMP' : timestamp,
	'ACCESS-SIGN' : signature,
	'Content-Type' : 'application/json'
}

response = requests.post( base_url + path_url , data = body , headers = headers)
print( response.status_code )
print( response.json() )


今まで当ブログで紹介した中では、一番長いpythonコードが出てきました。「ほら…やっぱり、プログラムは難しいじゃないか…騙された….」と思った方もいるかもしれません。

ですが、上記をすべて自分で書く必要は全くありません。実は、「買い注文をするコード」を1行書くだけで実行してくれる便利な「ライブラリ」が存在するからです。

「なんだよ!だったら最初からそれを教えろよ!」と思うかもしれません。ちゃんと次の記事からはその方法を紹介します。しかし、1度だけでいいので、「自分でAPI経由で注文してみる」ということをやってみることをお勧めします。

応用力をつけて欲しい

CCXTなどの便利なライブラリは、結局のところ、内側でBitflyerのAPIを呼んでいるだけにすぎません。なので、内側で「どのようなことが行われているのか?」のイメージを掴んでおくことは、今後、自分で自動売買BOTを作る上で絶対に必要です。

そのイメージがないと、「ライブラリでどんなことが可能なのか?」「どのようなカスタマイズが可能なのか?」「なぜ自分のコードが動かないのか?」「エラーが出た場合、どこに原因がありそうか?」が全く理解できなくなり、応用ができなくなるからです。

内側で各取引所のAPIを呼んでいることを理解していれば、よりライブラリを便利に使いこなすことができます。BitflyerのAPIを直で使って注文を出すのは、今回の記事の1回限りなので、1度だけ勉強だと思って付き合ってみてください。

ソースコードの意味を解説

繰り返しになりますが、プログラム初心者の方は、最初から自分でソースコードを書く必要はありません。最初に目指すべきなのは、「ソースコードを自力で読めるようになること」「読めば、大体、何をやっているのか理解できるようになること」です。

読めるようになれば、ネットに落ちているソースコードを拾って、どの部分をカスタマイズすれば「やりたいこと」ができるのか、のアタリを付けることができます。

ここでも上記のソースコードの意味を上から純に説明していきます。

importするライブラリ

import hashlib
import hmac
import requests
import datetime
import json

まず最初にこのプログラムで必要なライブラリをインポートします。

hashlibとhmacは、APIシークレットを暗号化して送るために使うライブラリです。requestsはAPIリクエスト(https://api.bitflyer.jp/~)を送るためのライブラリです。

datetimeは現在時刻を取得するためのライブラリです。どの取引所でもAPIで注文を出すときには、現在時刻(タイムスタンプ)をリクエストに含めるのが普通です。またjsonは、指値価格や注文量などのパラーメータをJSON形式に変換するために使います。

必要な情報を揃える

api_key = "APIキーを入力"
api_secret = "APIシークレットを入力"

base_url = "https://api.bitflyer.jp"
path_url = "/v1/me/sendchildorder"
method = "POST"

ここは見れば意味がわかると思います。
今回のプログラムで必要なURLやAPIキーなどの情報を最初に変数に入れておきます。また今回はPOSTメソッドで通信するので、methodという変数も用意しておきます。

timestamp = str(datetime.datetime.today())

現在時刻を、datetime.datetime.today()で取得します。
この日付データを「文字」に変換するために、str()で囲っています。文字に変換しないとhttps通信で送れないからです。変換した結果を、「timestamp」という変数に入れておきます。これも後で使います。

注文に必要なパラメーターをセット

param = {
	"product_code" : "FX_BTC_JPY",
	"child_order_type" : "LIMIT",
	"side" : "BUY",
	"price" : 指値価格を入力,
	"size" : 0.01,
}
body = json.dumps(param)

これは、先ほど確認したように、bitFlyerのAPI注文で必要になるパラメーター(通貨の種類、指値/成行、ロング/ショート、指値価格、注文ロット数)です。

これをparamという変数にセットして、それをjson.dumps()でJSON形式に変換します。JSON形式にしないと、HTTPS通信のデータとして送れないからです。JSON形式に変換したデータは、bodyという変数に入れておきます。

これらのbodyのデータは、通信データの「ボディ」という部分に入れて送ります。メールの本文に該当するイメージです。

認証のための暗号文(署名)を作る

message = timestamp + method + path_url + body
signature = hmac.new(bytearray(api_secret.encode('utf-8')), message.encode('utf-8') , digestmod = hashlib.sha256 ).hexdigest()

最初に読んだとき、この部分が一番、「難しい…わからない…」と思った方が多いかもしれません。

この部分では、「この注文メッセージを作って送っているのが、本当にあなた本人である」「成りすましや通信途中での改竄がされていない」ということを証明するために、APIシークレットを鍵にして、本文を暗号化(署名)しています。

いわゆるメッセージ認証コード(HMAC)という認証のための暗号アルゴリズムですが、暗号分野に興味のある方以外は、深く理解する必要はありません。単に何となく「こう書くものなんだ」と考えておいてください。興味がある方は、「hmac() python」で検索すればわかります。

通信データのヘッダーを作る

headers = {
	'ACCESS-KEY' : api_key,
	'ACCESS-TIMESTAMP' : timestamp,
	'ACCESS-SIGN' : signature,
	'Content-Type' : 'application/json'
}

ここでは、通信データのヘッダーを作っています。
メールのヘッダーのようなものですね。ここに、「APIキー」「現在時刻」と、さきほどの「暗号署名」をセットします。これで通信文の準備はできたので、あとはbitFlyerのサーバーに送るだけです。

APIリクエストを送る

response = requests.post( base_url + path_url , data = body , headers = headers)
print( response.status_code )
print( response.json() )

requests()関数を使って、指定したURL(https://api.bitflyer.jp/~)宛に、さっき作った通信データ(bodyが注文情報、headersがAPIキーや署名)を、postメソッドで送っています。そしてサーバーから返ってきた情報を、responseという変数に入れています。

このrequests()は以前の記事でも何度も使いましたね。Pythonのプログラミングではめちゃくちゃよく使う関数なので、何となく慣れておきましょう。最後の2行は、bitFlyerのサーバーから返ってきた情報を、プロンプト(黒い画面)に表示するためのコードです。

実行してみよう!

上記のコードをエディタに打ち込んでください。
丸々コピペしてもいいですが、意味を考えながら自分の手で書き写した方が、プログラミングの上達は早くなります。

できたら、いつものように「test.py」というファイル名で保存して、Anacondaプロンプトで実行してみましょう。以下のように表示されれば成功です!

200
{'child_order_acceptance_id': 'JRF20180314-181041-090404'}

実際にbitFlyerのトレード画面にログインして注文状況を見てみましょう。ちゃんと注文が入っているのが確認できました。

今回はテストなので間違って刺さらないように、現在価格が90万円のところ、80万円で買い指値を入れました。普通に「×」ボタンを押せば、注文をキャンセルできます。

もし動かなかった場合

長いpythonのソースコードを自分で手打ちして動かした場合、1発では動かない方が普通なので安心してください。プログラミングはエラーを試行錯誤しながら修正する過程でしか上達しません。1発でエラーのないコードを書ける人はいません。

大抵は何かしらの打ち間違いなので、エラーをよく読んでください。

何行目のエラーかを確認する

「line 33」とあるので、33行目が何かしら間違ってるとわかります。
「name ‘signatuer’ is not defined」と書いてあります。名前がおかしいようですね。ここでは、「signature」のスペルミスでした。

ステータスコードを確認する

先頭に「404」と書かれています。
これはpythonのプログラム自体は正しく書けていて、通信データ自体は送れたものの、bitFlyerのサーバーから「404」エラーが返ってきていることを意味しています。

「404」はサーバー側で、リクエストURLが見つからなかった場合のステータスコードです。ここでは、指定したAPIのURLを書き間違ってました。ステータスコードを表示することで、エラーの原因を絞りこむことができます。

HTTPステータスコード一覧

最後に

前述のように実際に自動売買BOTを作る際には、外部の方が作ってくれている便利な「ライブラリ」を使います。例えば、次の記事からはCCXTというライブラリを使います。それを使えば、今回のような買い注文を出すコードは1行で書けます。

ただし知っておいて欲しいのは、ライブラリはbitFlyerの公式が提供しているAPIではないということです。そのため、利用は自己責任になります。皆が使っているようなライブラリで、かつgithubなどで全コードが公開されているものは、ある程度は安全だと思いますが、一応、危険性は理解しておいてください。

また便利なライブラリとはいっても、基本的には、内側で各取引所のAPIを叩いているだけです。なので、ライブラリを使っていて何か行き詰った場合は、「裏側でどのAPIを使ってるのか?」を考えたり調べたりしてみると、解決のヒントになります。

(練習問題)

自分で上記のコードをカスタマイズして、売り(ショート)注文を出してみてください!^^ ※ 指値価格を変え忘れるとすぐに約定してしまうので注意してね!

BitflyerのAPIキーとシークレットを取得しよう

第2回の記事で、「APIとは何か?」を説明し、実際にパブリックAPIを利用してbitFlyerの板情報を取得する方法を説明しました。覚えていますか?

そのときにも説明しましたが、実際に売買注文をAPI経由で出したり、自身のJPY残高を確認したりするためには、「プライベートAPI」を利用する必要があります。今回の記事では、プライベートAPIを利用するのに必要なパスワード(=APIキー・シークレットといいます)を取得しておきましょう。

APIキー・シークレットの取得

まずは「bitFlyer lightning」にログインしてください。
(bitFlyerのアカウント登録がまだの方は、ぜひこちらから登録してください)

▽ bitFlyer lightningのログイン後の画面

ログインしたら、左上の「三」MENUマークをクリックして、メニューの一覧から「API」をクリックしてください。

「新しいAPIキーを追加」をクリックします。

免責をキチンと読んだ上で「同意」してください。

APIキーの権限の設定

以下のような画面が出てきます。
これはAPI経由での命令について「どのような行為まで許可するか?」という権限の設定です。

ここでチェックを入れた項目については、APIキーとシークレットを知っていれば、誰でも実行することができます。つまり万が一、APIキー・シークレットが漏洩した場合には、実行されてしまう可能性のある項目です。

単に自動売買BOTを作るだけなら、入出金の機能は不要なので、すべて外しておきましょう。特に銀行への「出金」の指示をBOT経由で出すことはまずないと思うので、「出金」は外しておいてください。

「資産」と「トレード」の項目はすべてチェックを入れて構いません。(権限は後からでも変更できるので、あまり考えこむ必要はありません)

またラベルは単に自分がAPIキーを識別するためのものなので、何でも構いません。「自動売買BOT作成用」とでもしておくといいでしょう。これで「OK」を押せば、APIキーの作成が完了します。

APIキーとシークレットを厳重に保管する

作成が完了したら以下の画面になります。
「表示」の部分をクリックした上で、API KeyとAPI Secretをメモして安全ば場所に保管してください。

このブログは、仮想通貨トレードのブログなので、暗号技術に多少興味のある方も見ていると思います。そのため、一応、簡単にAPIシークレットの意味を説明しておきましょう。(興味のない方は以下の段落は読み飛ばしてくださいw)

API注文の暗号化の仕組み

API経由でbitFlyerに売買注文などの命令を出すときは、「メッセージ認証コード」(HMAC)という暗号技術が使われています。この方式では、APIで実行したい指示の内容を、APIシークレットとセットにしてハッシュ値を計算し、そのハッシュ値をWEB経由で送ります。

そのため、もし通信内容が途中で漏洩したとしても、そこからAPIシークレットが判明することはありません。またAPIシークレットを知らないとハッシュ計算ができないので、APIシークレットを知らない人が、自分に成りすまして勝手に注文を偽装することもできません。

APIキーの方は、平文のまま通信のヘッダーに含まれて送信されます。とはいえ、こちらもhttps通信で暗号化されていますので、一般論としていえば、通信内容を傍受することはできません。要するに、APIキーとシークレットは、通信途中で漏れることはない、という話です。

【重要】信用できないソースコードにAPIシークレットを入力しないこと

ただし初心者の方に気を付けて欲しいのは、自分のよく理解していない売買BOTのプログラムやライブラリに、「安易にAPIシークレットを渡してはいけない」ということです。

上記のように通信の途中で、第三者に傍受されてAPIキー・シークレットが漏洩することはありません。しかし、自分の理解していないPythonのソースコードにAPIシークレットを入力すると、そのPythonプログラムがどこか第三者にこっそりAPIシークレットを送信している可能性は0ではありません。

ソースコードはなるべく読んで意味を理解しながら書き写し、また外部のライブラリを使う場合は、githubなどでソースコードが公開されているもの、有名で皆が使っているもの、を使うようにしましょう。

またAPIキーの権限には、出金などの権限を与えず、常に必要最小限にしておくことが大事です。

次回:BitflyerのAPI経由でpythonで「買い注文」を出そう!

自動売買BOTを作る上で最低限絶対に必要なプログラミング構文

この記事では、文系初学者でも自動売買BOTを動かすために、プログラムのソースコードを「何となく読んで理解できる」レベルになることを目指します。そのために、最低限、必要なプログラミングの構文知識を3つだけ説明します。

それが、for文/if文/while文です。

実際のところ、単純なアルゴリズムによる自動売買BOTであれば、この3つの構文をキチンと理解するだけで実装が可能になります。

学習のポイント

当ブログはプログラミング学習サイトではないので、教科書のような詳しい構文の書き方は説明はしません。最低限、これらの3つの構文がどういう雰囲気で動くものなのか、ここでは大雑把に理解することを目指してください。

あとは当ブログに出てくる実際のソースコードを手打ちしたり、カスタマイズしながら実践で覚えていってください。キチンと基本を勉強したい方は、他の学習サイトを参考にしたり、一番簡単そうなPythonのプログラム教本を1冊だけ読むといいでしょう。

for文について

for文というのは、簡単にいうと、「〇個の要素すべてについて、1つずつ同じ処理を実行していきたい。だけど同じソースコードを〇回書くのは面倒くさい」というときに使います。

構文は以下のような感じです。

for 要素 in 配列等
   要素について1つずつ実行したい処理

例えば、ある仮想通貨の取引所で、取扱いのある通貨ペアをAPIで取得したところ、以下のような配列が返ってきたとします。

product = [“BTC_JPY”,”ETH_BTC”,”XRP_BTC”,”XEM_BTC”,”BCH_BTC”,”TRX_BTC”,”LTC_BTC”,……..]

これをすべてAndcondaプロンプト(黒い画面)に表示したい場合、以下のように書くことができます。

print(product[0])
print(product[1])
print(product[2])
print(product[3])
print(product[4])
print(product[5])
print(product[6])
print(product[7])
print(product[8])
....

しかし同じprint()を何度も書くのは面倒くさいですよね。

6~7回程度ならまだいいですが、過去2年分の価格データとか、すべての約定履歴とか、データ数が膨大になってくると、とても1つ1つを書くことはできません。しかも上記のように書く場合には、あらかじめデータ数が何個あるのかを数えて調べなければなりません。

for文を使えば、これを以下のようにシンプルに書けます。

for p in product:
	print(p)

これだけです!

上記の2行は、productという配列の中にある要素の1つずつを順番に「p」という変数に入れて、それをprint(p)で、黒い画面に出力する、という意味のプログラムです。

実践的な例

もう1つだけ、実践的な例をあげてみましょう。

「10日間の単純移動平均線を当日の終値が上回って引けた場合」をエントリーまたは利確の条件の1つ(フィルター)として使いたいとします。そこで過去のビットコインの終値の価格をAPIで取得したところ、以下のようなデータが得られました。

price = [1012104,1064332,981452,1026681,1040899,1103870,1214016,1346433,1319455,1312633]

知りたいのは、当日の終値が過去10日間の単純移動平均を上回ったかどうかなので、この平均を求めます。もしこれをfor文を使わずに書くとしたら、以下のようになります。

sum = 0
sum = sum + price[0]
sum = sum + price[1]
sum = sum + price[2]
sum = sum + price[3]
sum = sum + price[4]
sum = sum + price[5]
sum = sum + price[6]
sum = sum + price[7]
sum = sum + price[8]
sum = sum + price[9]

average = sum/10
print(average)

こちらもなかなか面倒くさいですね。
10期間単純移動平均くらいなら何とかなりますが、100期間移動平均などになると、とても手では書けません。これはfor文を使うと以下のように書けます。

sum = 0
for p in price:
	sum = sum + p
average = sum/10
print(average)

これだけです!
データが何百個あったとしても、上の5行だけで平均を調べることができます。

for文について、とりあえず知っておくべき基本的な説明はこれで終わりです。他にも、数字で指定した回数だけ実行するなど、いろいろと応用的な書き方はありますが、新しく出会うたびにGoogleで調べていけば問題ありません。

if文について

if文というのは、「〇〇の場合には~したい、××の場合には~したい、それ以外の場合には~したい」といった条件分岐を書くための構文です。おそらく自動売買BOTでも一番使うことになります。

構文は以下のかたちになります。

if 〇〇のとき:
   実行したい処理

簡単ですね。
もし、「それ以外の場合は~」までセットで書きたければ、以下のように書きます。

if 〇〇のとき:
   実行したい処理
else:
   それ以外で実行したい処理

3つ以上の条件分岐を書きたいときは、以下のように書きます。

if 〇〇のとき:
   実行したい処理
elif 〇〇のとき:
   実行したい処理
elif 〇〇のとき:
   実行したい処理
elif 〇〇のとき:
   実行したい処理
else:
   それ以外で実行したい処理

とりあえず、このイメージだけ理解しておいてください。あとは実際のソースコードを読んだり書き写したりしながら、使い方を確認していけば問題ありません。

実践的な例

せっかくなのでさっきの続きをやりましょう。
過去10日の終値の単純平均は、114万2187円でした。もし当日の終値がこれを上回っていたら買いエントリー、下回っていたら何もしない、というプログラムを、さっきの続きで書いてみましょう。

当日の終値は118万2475円だとします。

today_price = 1182475
sum = 0

for p in price:
	sum = sum + p
average = sum/10

if average <= today_price:
	print("買いエントリーする")
else:
	print("何もしない")

付け足したのは、最初の「today_price = 1182475」の部分と、最後のif文のところです。

この例では、当日の終値が過去10日の単純移動平均より大きければ、「買いエントリーする」と画面に表示します。そうでなければ「何もしない」と画面に表示します。実際の自動売買BOTでは、この「買いエントリーする」のところに、買い注文の関数を入れることになります。

while文について

最後はwhile文です。
while文というのは、「ある特定の条件を満たしている間は、ずーっと永久に以下の処理をループしてください」という構文です。

構文は以下のようになります。

while 条件:
   ループしたい処理

自動売買BOTを作る場合だと、例えば、10秒間おきに価格やテクニカル指標をチェックして、シグナルが出たら売る・買う・手仕舞う・損切りする、といった処理を、放置で自動的にループさせたい場合などに使います。

例えば、以下のようなイメージですね。

while true:
  APIで価格を取得する
  シグナルを計算する

  if ポジションを持っていない:
    if 買いシグナルが出た:
      買い注文を出す
   else:
    if 利確シグナルが出た:
      利確注文を出す
    elif 損切シグナルが出た:
      損切注文を出す

  sleep(10)//10秒待機

こちらは物凄く大雑把なロジックですが、

(1)価格を取得してシグナルを計算する
(2)まだポジションを取ってなければ、買いシグナルを確認し、シグナルが出ていれば買い注文を出す。出ていなければ何もしない。
(3)もし既にポジションを取っていれば、利確シグナルを確認する。シグナルが出ていれば利確注文を出す。出ていなければ、損切シグナルを確認する。シグナルが出ていれば損切注文を出す。両方出ていなければ何もしない。
(4)10秒間待機して、また(1)に戻る

というアルゴリズムを永久にループさせることができます。

この「シグナルを計算する」と書いた部分に、先ほどのfor文を使った実践例を組み込めば、「終値が短期移動平均を上回ったときに買い、下回ったときに売る」といった、ごくシンプルなアルゴリズムを作ることもできます。

ここでは大体、どのようにwhile文を使うのかのイメージが掴めればOKです。

CryptowatchのAPIで取得したbitcoin価格のJSONデータから欲しい数字を取り出す

前回の記事(「JSON形式のデータから自由に数字を取り出そう」)の、練習問題の答え合わせです。

まずCryptowatchのAPIで、過去のbitFlyerのビットコイン価格(日足データ)をまとめて取得します。この手順については、すでに説明済み(こちらの記事)なので省略します。以下のAPIをそのまま使ってで説明を進めていきます。

https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc?periods=86400&after=1514764800

このAPIでは2018年1月以降の日足データを取得しています。ここから、2018年1月16日、ビットコイン価格の大暴落があった日の終値と最安値を取得してみましょう。

取得したJSONデータの構造を把握する

取得したデータの最初の方の部分を切り取ってみると、以下のような構造になっていることがわかります。

{"result":{"86400":[[1514764800,1519999,1713306,1502242,1675100,20188.11,32083065000],[1514851200,1673600,1684270,1568150,1635320,10534.478,17226760000],[1514937600,1637228,1760110,1600000,1725726,10670.864,17824102000],....

最初の部分だけを見ると、

{“result”:{“86400”:[[

で始まっていますね。

この先のデータがものすごく長いのですが、少なくともこの先頭の文字列を見るだけでも、以下のようなデータ構造になっていることはわかります。

{ “result”: {“86400”: [[xx,xx,xx…],[xx,xx,xx…],[xx,xx,xx…]] }}

一番内側に

[xx,xx,xx…]

という数字が7個含まれた配列値のデータ群があり、これが1日分のデータです。

このデータ群が日付分だけ存在します。
つまり以下のように集まって、

[ [],[],[],[]…. ]

という大きな1つの配列値のデータ構造になっています。さらにこの大きな1つの配列値のデータが、

{ “86400” : [ [],[],[],[]…. ] }

と、{} のカッコで括られているため、”86400″(日足)をキーとして、[]内のデータ全てを1つの値とするデータ構造になっていることがわかります。さらに上記の{}内のすべてのデータを1つの値として、

{ “result” : {1つのデータ} }

と、result をキーとする構造になっていることがわかります。
ここで前回の記事で勉強したことを思い出せば、Pythonのプログラムで一番内側の価格データを指定するためには、

data[“result”][“86400”][0][0]

というように指定すればいいことがわかります。
※ 0 のところには、「左から何番目のデータか?」という数字が入ります。

目的の日付データを探す

さて、次に2018年1月16日(ビットコイン価格の大暴落があった日)のデータを探します。一番内側の数字データが、以下の順番で記載されていることはすでに説明しました。

[ 取引時間(クローズ) , 初値 , 高値 , 安値 , 終値 , 出来高 ]

実際に、JSONデータの先頭のUNIXタイムスタンプを、いくつか日時に直してみればわかりますが、Cryptowatchの価格データは毎日午前9時で区切られて日足データとしてまとめられていることがわかります。

ということは、2018年1月16日の暴落時の最安値が含まれた価格データを探すには、「2018年1月17日午前9時」までを区切りとするデータのまとまりを探せばいいことがわかります。これはUNIXタイムスタンプに変換すると、「1516147200」です。

UNIXタイムスタンプ変換ツール

JSONデータの配列値は、左から順番に0番目、1番目、2番目….、と数えることを思い出してください。

つまり今回の目的の価格データを探すためには、一番内側の[]のデータのまとまりのうち、先頭(0番目)が「1516147200」で始まっているデータの3番目の数字を取り出せばいいことがわかります。

このデータをどうやって探すのか?

さて、「自分で試してみてください」といっておいて申し訳ないのですが、実はここまで勉強した内容だけだと、ここで行き詰ってしまいます。なので、この部分までたどり着けた方はいったん合格です(笑)

ここから先に進むには、少し新しいプログラミングの知識が必要になります。

なぜなら先頭に「1516147200」を含むデータ群、[xx,xx,xx,xx….]が、その一つ外側のデータ構造[ [],[],[],[]….. ]の何番目にあるのかが、わからないからです。

前回の記事で紹介したbitFlyerのAPIのように、すべてのデータが、{ キー:値 } の形式になっていれば、キーを指定するだけで値を取り出すことができます。しかし、[[],[],[],[]…..]のようなデータ構造の場合は、目的の数字が何番目の[]に入っているのか、自分で調べなければわかりません。

for文を使ってループで探す

このような場合は、pythonのプログラミングで(先頭から順番に)片っ端から調べる、という方法を取ります。つまり、先頭の[]から順番に見ていき、一番内側の[]の先頭の数字が「1516147200」に一致するものを取り出す、というプログラムを組みます。

JSONのデータ形式によっては、このような処理が必要になることも多いので、ソースコードを理解しておきましょう。エディタを起動して以下のようなプログラムを書いてみてください。

import requests
response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc?periods=86400&after=1514764800")
data = response.json()

for item in data["result"]["86400"]:
	if item[0] == 1516147200:
		print(item[3])

先頭から4行目までは前回の記事と全く同じです。
なので、新しく出てきたforのところから意味を説明します。

for文とif文の意味

文系の初学者の方が、できるだけ勉強をすっ飛ばして、実践からプログラミングを始める場合でも、どうしても絶対に「if文」と「for文」だけは理解していないと先に進めなくなります。

for文/if文の概念自体が全くわからない方は、できれば以下の記事を先に読んで少しだけ勉強してみてください。15~30分くらいで大体、要領だけはつかめると思います。

自動売買BOTを作る上で最低限必要なプログラミングの構文

今回のコードの意味

今回のJSONデータは、{ “result”: {“86400”: [[0番目],[1番目],[2番目]….]} というデータ構造になっており、知りたいのは何番目の[]に、2018年1月16日の価格データが含まれているか?です。

[]の中の先頭(0番目)に日付の数字が含まれていて、3番目に最安値の価格が含まれていることはすでに知っています。

data[“result”][“86400”][???][0]

が 1516147200 に一致する場合に、

data[“result”][“86400”][???][3]

の数字を取り出せばいいことになります。
つまり、for文のループ処理としては、

data[“result”][“86400”][0]
data[“result”][“86400”][1]
data[“result”][“86400”][2]
data[“result”][“86400”][3]
data[“result”][“86400”][4]
data[“result”][“86400”][5]
data[“result”][“86400”][6]


というのを順番に自動的に試していけばいいわけです。

for item in data[“result”][“86400”]: の部分では、86400をキーとするデータの値( [[0番目],[1番目],[2番目]….] のこと)の中の要素について、[ 〇番目 ] のデータを1個ずつ item という変数名に置き換えて、for文のループ処理を実行しています。

また、一番内側の[]の先頭の数字が「1516147200」に一致するかどうかは、if文で判定します。こちらは、現在、for文でループしている

data[“result”][“86400”][?番目]
(→ これをfor文の中では item に置き換えている)

のデータのうち、

data[“result”][“86400”][?番目][0]
(→ これはfor文の中では、item[0] に置き換えられる)

が、「1516147200」に一致すればいいわけです。そのため、if item[0] == 1516147200:という条件分岐を記述し、一致した場合にはその3番目の要素(item[3])を、print()で黒い画面に表示するように指示しています。

実行してみる

これをAnacondaプロンプトで実行してみます。

最安値は101万5000円でした。

この日の最高値は168万1000円、前日の終値は171万7000円ですから、この1日で70万円近くも暴落したことになりますね。(ぜひ練習として、この日の最高値や前日の終値も取得してみてください)

JSON形式のデータから自由に欲しい数字を取り出そう

前回までの記事では、APIを叩いて過去のビットコインの価格データを取得したり、現在の取引所の板情報を取得する方法を説明しました。

API経由で取得したデータは、大体、以下のように、空白も改行も装飾もない数字と文字の羅列データです。

※bitFlyerのAPIで取得した約定履歴のデータ

このような形式のデータを「JSON形式」といいます。このままの形式だと、どうしていいかわからないと思います。そこで、このJSON形式のデータから欲しい数字だけをPythonで取り出す方法を説明します。

目的の数字だけを取り出す

この記事では、「JSON形式とは何なのか?」といった面倒くさい説明に立ち入ることはしません。興味がある方は自分で調べてみてください。ここでは、いきなり本題に入り、「どうやって目的の数字を探すか?」だけを説明します。

JSON形式のデータは、以下のようなカッコ[]で括られて記述されています。


[ 12320 , 12342 , 12246 , 12254]

このように、JSONでは[]で囲まれたデータを1つのまとまりとして扱います。(このような形式を配列値といいます)

そしてプログラムの世界では、これらの[]の中のデータを左から順に、0番目、1番目、2番目、3番目…とカウントします。一番左のデータは[0]、2番目のデータは[1]、3番目のデータは[2]と書いて指定します。

ここまでまずは、覚えておいてください。

JSON形式のデータには、もう1つの記述方法があります。
それが以下のような別のカッコ{}で囲う記述です。


{ “btc”:1205314 , “eth”:102478 , “xrp”:89.45 , “xem”:48.42 }

こちらはさっきと違い、1つのデータが「〇〇:××」という2つの値のセットで記述され、それが{}の中にたくさん格納される、という記述の形式です。(このような形式をオブジェクト値といいます)

「〇〇:××」というデータセットのうち、左側の〇〇をキー、右側を値といいます。こちらの{}のデータ形式は、キーを指定することで値の数字を取り出します。例えば、「”btc”:1205314」というデータであれば、btcというキーを指定することで、1205314という値を取り出すことができます。

さっきの[]のデータ形式と違って、順番(〇番目のデータ)で数字を指定することはできません。

はい、覚えるルールはこれだけでOKです。

複雑に見える入り組んだデータ形式

上記のようにJSON形式は、[]や{}のカッコを使ってデータをひとまとめにして扱う形式ですが、実際には、カッコの中にさらにカッコがたくさん入ったような入れ子構造になっている場合が多いです。

例えば、以下のようなイメージです。

{ “中学生”: {“1年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]} , “2年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]} , “3年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]}}, “高校生”: {“1年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]} , “2年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]} , “3年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]}}}

数字は適当なので気にしないでください(笑)

いきなりこれを見ると少し面食らうかもしれませんが、一番内側から分解してみていけば、データの構造がわかります。

データの取り出し方

一番内側のデータセットはこれです。

“男子”:[156,47]

これは左側の”男子”がキーで[156,47]が値のデータセットです。ちなみにこの値は0番目が身長で1番目が体重です。なので、男子の身長の数字にアクセスしたければ、Pythonで[“男子”][0]と書けば、指定できます。

その外側は、

{“1年生” : {“男子”:[],”女子”:[]}}

という構造になっていますね。これは、左側の”1年生”をキーとし、右側の{“男子”:[],”女子”:[]} をまるまる1つの値とするデータセットです。そのため、ここから男子の身長データを取り出したければ、Pythonで[“1年生”][“男子”][0]と書けばOKです。

一番外側の{}を見ると、

{ “中学生”: {1年生のデータ,2年生のデータ,3年生のデータ} , “高校生”:{1年生のデータ,2年生のデータ,3年生のデータ}}

の構造になっているのがわかります。そのため、もし高校2年生の女子の体重データを取り出したければ、Pythonで[“高校生”][“2年生”][“女子”][1]と記述すればいいことがわかります。

bitFlyerのAPIで試してみよう

では同じことを、前回の記事で勉強したbitFlyerのパブリックAPIで試してみましょう。今回は、現在のティッカー情報を取得する以下のAPIを使います。

https://api.bitflyer.jp/v1/ticker/

すると、以下のような結果が得られました(3月現在)

{"product_code":"BTC_JPY","timestamp":"2018-03-12T13:46:52.657","tick_id":2658019,"best_bid":1053564.0,"best_ask":1053565.0,"best_bid_size":0.06,"best_ask_size":0.01,"total_bid_depth":2960.87621693,"total_ask_depth":3323.14800491,"ltp":1053575.0,"volume":273330.16902808,"volume_by_product":25246.19923669}

今ならあなたもこのJSON形式のデータ構造の意味がわかるはずです。

ではPythonのプログラムで、上記のJSONデータから「買い気配値」だけを取り出してみましょう。※ 買い気配値とは、買い板にある注文のうち一番価格の高い注文価格のことをいいます。(参考記事

Pythonプログラムを書く

サクラエディタを起動して以下のように記述してみましょう。

import requests
response = requests.get("https://api.bitflyer.jp/v1/ticker/")
data = response.json()
print( data["best_bid"] )

一応、いつものようにこのプログラムの意味を説明しておきます。
なお1行目と2行目は前回の記事と同じなのでそちらを参考にしてください。

data = response.json()
URLから取得したJSON形式のデータをパースして、dataという名前の変数に入れます。これは簡単にいうと、pythonに「これはjsonデータだよ!」と教えてる、というくらいの意味に考えてください。この1行を書くことで、JSONデータとして取り扱うことができます。

print ( data[“best_bid”] )
さっきの data というJSONデータから、”best_bid”をキーとする数字を取り出して、それを print() で黒い画面に表示しています。この data[“best_bid”] を自分で書ければ、今回の記事の目標は達成です!

さて、これをAnacondaプロンプトで実行してみると、買い気配値を得ることができました。

長いデータの中から買い気配値だけを取り出すことができました。

もう少しだけ難しい練習問題

今回のデータは、{}が1個しかなくて全体の構造がシンプルだったので、簡単でしたね。もう少しだけ難しいJSONデータのパースに挑戦してみましょう。

前々回の記事で練習した、過去のビットコイン価格のデータを取得するAPIを利用して、2018年1月16日(ビットコインの価格の大暴落があった日)の終値と最安値を取得してみてください。利用するAPIは以下です。

https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc?periods=86400&after=1514764800

こちらはさっきより少し難しいですが、まずは自分で試行錯誤してみてください。なお、人間の日付(2018-01-16)を機械のUNIXタイムスタンプに変換するには、こちらのサイトを使ってください。

UNIXタイムスタンプ変換ツール

なお、こちらの練習のプログラムを書くためには、最低限の簡単な「if文」と「for文」を書く必要があります。if文とfor文だけは、プログラムを書く以上、どうしても絶対に勉強する必要があります。全くわからない方は、以下の正解記事を先に読んでおいてください。

正解は、以下の記事で解説しています。

練習問題の解説記事

JSONデータの取扱いまとめ

これであなたはPythonを使って、API経由で取得したデータの構造を把握して、目的の数字を自由に取り出すことができるようになりました!

この記事で学んだ内容は、例えば、API経由で「注文の一覧」を取得したり、現在のJPY残高を確認したり、「注文ID」を管理して約定しない注文をキャンセルしたり、自動売買BOTを作るすべての場面で使います。APIのあらゆる結果(レスポンス)はJSON形式で返ってきますので、このスキルは必須です。

次はいよいよ、bitFlyerのプライベートAPIを利用して、買い注文・売り注文を出すために必要なことを学んでいきましょう。