前回は、Binanceでアカウントを作成して、APIキーを入手する方法を扱いましたが、今回はBinanceの公式ライブラリを導入して、実際にAPIを使用する方法について扱いたいと思います。

仮想通貨は、正式には「暗号資産」という呼称で統一するよう金融庁を中心に啓蒙されているようですが、一般的にはまだ「仮想通貨」という呼称の方が、広く普及しているように思います。それでこの記事では仮想通貨という呼び方をしています。

スポンサーリンク




目次

  1. Binanceライブラリの導入方法
  2. APIの基本的な使い方
  3. 特定通貨の価格、高値、安値を取得するには?
  4. 統計的に仮想通貨の情報を取得する方法
  5. まとめ

1. Binanceの公式ライブラリの導入方法

Binanceの公式ライブラリは「pip」で簡単に導入できます。「pip」とは、Pythonのパッケージをインストールするための管理ツールです。この記事ではMacを前提に話を進めますが、Macの場合は最初からpipを使うことができます。

まずpipのバージョンを確かめてみましょう。

Python 2.7系

$ pip -V

こんな風にバージョンが表示されます。

$ pip 19.2.3 from /Library/Python/2.7/site-packages/pip-19.2.3-py2.7.egg/pip (python 2.7)

最新版にアップグレードする場合は、下記のコマンドを使ってみましょう。

$ pip install –upgrade pip

Python 3系

$ pip3 -V

こんな風にバージョンが表示されます。

$ pip 19.1.1 from /usr/local/lib/python3.7/site-packages/pip (python 3.7)

最新版にアップグレードする場合は、下記のコマンドを使ってみましょう。

$ pip3 install –upgrade pip

ここまで確認できたら、早速、Binanceの公式ライブラリをインストールしてみましょう。

$ pip install python-binance

導入はたったこれだけです!

2. APIの基本的な使い方

Binanceの公式ライブラリを使うには、プログラムの冒頭でこのようにインポートします。

from binance.client import Client

では、早速動かしてみましょう。

エディターで下記のように記述して、仮に「get_all_tickers.py」として保存してみましょう。

# -*- coding: utf-8 -*-
from binance.client import Client
# APIキー、シークレットキー設定
client = Client('あなたのAPIキー', 'あなたのシークレットキー')
# 全ての価格を取得
prices = client.get_all_tickers()
# 戻り値を出力
print('prices: ' + str(prices))

そして実行してみます。

$ python get_all_tickers.py

このように出力されたでしょうか?

$ prices: [{u’symbol’: u’ETHBTC’, u’price’: u’0.01780500′}, {u’symbol’: u’LTCBTC’, u’price’: u’0.00559000′}, {u’symbol’: u’BNBBTC’, u’price’: u’0.00187110′}, {u’symbol’: u’NEOBTC’, u’price’: u’0.00120500′}, {u’symbol’: u’QTUMETH’, u’price’: u’0.01287200′}, {u’symbol’: u’EOSETH’, u’price’: u’0.01933200′}, {u’symbol’: u’SNTETH’, u’price’: u’0.00007313′}, {u’symbol’: u’BNTETH’, u’price’: u’0.00185600′}, {u’symbol’: u’BCCBTC’, u’price’: u’0.07908100′}, {u’symbol’: u’GASBTC’, u’price’: u’0.00013380′}, {u’symbol’: u’BNBETH’, u’price’: u’0.10499200′}, {u’symbol’: u’BTCUSDT’, u’price’: u’7141.64000000′}, {u’symbol’: u’ETHUSDT’, u’price’: u’127.13000000′}, {u’symbol’: u’HSRBTC’, u’price’: u’0.00041400′}, …以下省略… ]

get_all_tickers関数を使うと、Binanceで扱うすべての通貨の価格がjson形式で取得できるのです。簡単ですね。

戻り値に関してですが、以下のような構造で返ってきます。

{u’symbol’: u’ETHBTC(通貨ペアシンボル)’, u’price’: u’0.01780500(価格)’}

ところで、特定の通貨の価格だけ取得したり、価格以外の情報を取得するにはどうしたらいいのでしょうか?

3. 特定通貨の価格、高値、安値を統計的に取得するには?

では次に、特定の通貨のみの情報を取得する方法をやってみましょう。下記のように、get_ticker関数を使いますが、第一引数で通貨ペアシンボルを「symbol」として渡してやることで特定通貨の情報のみを取得することが可能です。

下記の例ではBTC建のETH(イーサリアム)を取得しています。以下のようにコードを記述して「get_ticker.py」として保存してみましょう。

# -*- coding: utf-8 -*-
from binance.client import Client
# APIキー、シークレットキー設定
client = Client('あなたのAPIキー', 'あなたのシークレットキー')
# 最新の価格を取得
ticker = client.get_ticker(symbol='ETHBTC')
# 戻り値を出力
print('ticker: ' + str(ticker))

そして実行してみます。

$ python get_ticker.py

このように出力されたでしょうか?

$ prices: [{u’symbol’: u’ETHBTC’, u’price’: u’0.01780500′}, {u’symbol’: u’LTCBTC’, u’price’: u’0.00559000′}, {u’symbol’: u’BNBBTC’, u’price’: u’0.00187110′}, {u’symbol’: u’NEOBTC’, u’price’: u’0.00120500′}, {u’symbol’: u’QTUMETH’, u’price’: u’0.01287200′}, {u’symbol’: u’EOSETH’, u’price’: u’0.01933200′}, {u’symbol’: u’SNTETH’, u’price’: u’0.00007313′}, {u’symbol’: u’BNTETH’, u’price’: u’0.00185600′}, {u’symbol’: u’BCCBTC’, u’price’: u’0.07908100′}, {u’symbol’: u’GASBTC’, u’price’: u’0.00013380′}, {u’symbol’: u’BNBETH’, u’price’: u’0.10499200′}, {u’symbol’: u’BTCUSDT’, u’price’: u’7141.64000000′}, {u’symbol’: u’ETHUSDT’, u’price’: u’127.13000000′}, {u’symbol’: u’HSRBTC’, u’price’: u’0.00041400′}, …以下省略… ]

この場合も戻り値はやはりjson形式ですが、帰ってくる様々なキーの値を拾うことで、価格以外の情報も取得することができます。

get_all_tickers関数やget_ticker関数に関してさらに知りたい方は、下記のリファレンスも参照してみてください。
https://python-binance-jp.readthedocs.io/ja/latest/binance.html

APIの仕様に関しては上記のURLで概ね確認できるのですが、キーの意味が詳しく解説されているわけではないので、それぞれの戻り値を見てこんな感じかな?と推測するしかありません。

例えば、始値、終値、高値、安値は以下で取得できるようです。

始値(今日の始値)
print(str(ticker[‘openPrice’]))

終値(問い合わせた瞬間の最新の価格)
print(str(ticker[‘lastPrice’]))

買いの最高値
print(str(ticker[‘bidPrice’]))

売りの最安値
print(str(ticker[‘askPrice’]))

戻ってくるキーの値はfloatなのでstringに変換してからprintします。また、この場合の「終値」ですが、取得毎に価格が異なるので、昨日の「終値」ではなく、APIを使って問い合わせたその瞬間の価格だと思われます。

また「openPrice」は「始値」のはずですが、取得毎に同じ価格が帰ってくるため、今日の「始値」だと思われます。「最高値」と「最安値」も取得毎に異なるので、問い合わせた瞬間の価格のようです。

通貨シンボルを変えたり、cronで定期的に情報を取得すれば、必要な情報をもっと統計的に取得できます。

4. 統計的に仮想通貨の情報を取得する方法

APIを利用して仮想通貨の自動売買システムを構築するには、通貨の価格を統計的に取得して、売買判断を実装することになるかと思います。

では、テストプログラムよりも少し本格的なコードを扱ってみましょう。ここでは、仮想通貨の相場情報を統計的に取得する基礎的なコードを書いてみたいと思います。

以下の仕様を想定しコードを書いてみました。

<想定した仕様>

  • 予め定められた特定基軸通貨の相場情報をcronで定期的に取得するためのスクリプト
  • 特定の通貨ペアの始値※1、終値、最高値、最安値を取得する
  • 取得した情報をcsv形式で保存※2

※1 「始値」についてですが、APIで取得したものは当日の始値で常に固定化されてしまうため、前回プログラムを動かした時の終値を「始値」とします。

※2 統計情報の保存先となっているcsvの1列目はAPIで参照する通貨ペアの参照元にもなっています。ここに列挙されている通貨ペアの情報を取得することを想定しています。

やり方、書き方はいろいろあるかと思いますが、ご覧になっていただいた方の何らかの参考になれば幸いです。もし間違いや質問事項等がありましたら、お問い合わせやTwitterなどでご連絡ください。

まずは下記のような通貨ペアリストの参照元、また保存先となるcsvを用意します。1行目は必ずこのようにしてください。1列目の通貨ペアリストは、サンプルでは全てUSDT建のものとなっていますが、別の基軸通貨ベースのものに変更することもできます。またリスト化する通貨をもっと増やすこともできます。それぞれの行に「0.0」が96あることにも留意してください。これは15分間隔で情報を取得した場合、24時間分の情報を保存し、以後上書きすることが想定されているためです。

通貨ペア,100.0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-
ADAUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
ALGOUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
ANKRUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
ATOMUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
BANDUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
BATUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
BCHABCUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
BEAMUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
BNBUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
BTCUSDT,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
…以下省略…

次いで、下記のようなコードを用意します。これはcronで一定間隔、例えば、5分間隔とか、15分間隔で実行します。仮に15分で回せば、15分足の24時間分のローソクチャートを作成するためのデータを取得できるはずです。

# -*- coding: utf-8 -*-
from binance.client import Client
import datetime
import time
import csv

# ---------- 設定 ----------

# csvファイル
PAIR_LIST_PATH = '/あなたの環境/pair_list_usdt.csv'

# APIキー、シークレットキー設定
API_KEY = 'あなたのAPIキー'
SERCRET_KEY = 'あなたのシークレットキー'

# ---------- 処理開始 ----------

# 通貨ペアシンボルリストを初期化
saved_pair_list = []

# 保存されていた通貨ペアのペアシンボルを開く
with open(PAIR_LIST_PATH) as r:
    reader = csv.reader(r)
    saved_pair_list = [row for row in reader]
r.close()

# 日時取得
dt = datetime.datetime.now()

# 通貨ペアの直近の変化率を格納するリストを初期化
new_pair_list = []
line = []
line_range = len(saved_pair_list[0])

# BinanceAPIにアクセス
client = Client(API_KEY, SERCRET_KEY)

# 全ての通貨ペアの直近の変化率を取得
for i in range(len(saved_pair_list)):

	if i == 0:

		# 古いラベルを順次入れ替え
		for n in range(line_range):
			if n == 0:
				line.append(str(saved_pair_list[i][0]))
			elif n == 1:
				line.append(float(saved_pair_list[i][1]))
			elif n >= 2 and n <= line_range - 2:
				old_label = saved_pair_list[i][n + 1]
				line.append(old_label)
			elif n == line_range - 1:
				# 日時の書式は「%Y/%m/%d %H:%M」で指定
				line.append(dt.strftime('%Y/%m/%d %H:%M'))

	elif i >= 1:

		# 通貨ペアのシンボルと古い価格を取得
		pair_symbol = str(saved_pair_list[i][0])
		old_percent = float(saved_pair_list[i][1])

		# 最新の価格を取得
		ticker = client.get_ticker(symbol=pair_symbol)
		open_price = 0.0 # 始値
		last_price = float(ticker['lastPrice']) # 終値
		bid_price = float(ticker['bidPrice']) # 買いの最高値
		ask_price = float(ticker['askPrice']) # 売りの最安値

		# apiの制限を超えないようするため遅延させる
		time.sleep(0.2)

		# 古い価格を初期化
		old_price = 0.0

		# 古い価格を順次入れ替え
		for n in range(line_range):
			if n == 0:
				line.append(pair_symbol)
			elif n == 1:
				line.append(old_percent)
			elif n >= 2 and n <= line_range - 2:
				old_price = saved_pair_list[i][n + 1]

				# 前の終値を始値として格納
				old_price_split = old_price.split()
				if len(old_price_split) == 1:
					open_price = old_price_split[0]
				else:
					open_price = old_price_split[1]

				line.append(old_price)
			elif n == line_range - 1:
				new_price = str(open_price) + ' ' + str(last_price) + ' ' + str(bid_price) + ' ' + str(ask_price)
				line.append(new_price)

		# 変化率の対制限象
		target_time = (line_range - 1) - int(48)
		target_price_split = line[target_time].split()
		if len(target_price_split) == 1:
			target_price = float(target_price_split[0])
		else:
			target_price = float(target_price_split[1])

		# 変化率を計算
		if(last_price == 0.0 or target_price == 0.0):
			last_percent = 0.0000
		else:
			last_percent = (last_price / target_price) * 100.0 - 100.0
			last_percent = round(last_percent, 4)

		line[1] = last_percent

	# 二次元リストとして追加
	new_pair_list.append(line)

	# lineの初期化
	line = []

# 二次元リストをソート
new_pair_list_sorted = sorted(new_pair_list, key=lambda x:x[1], reverse=True)

# 通貨ペアの直近の変化率を保存
with open(PAIR_LIST_PATH, 'w') as w:
	writer = csv.writer(w, lineterminator='\n')
	writer.writerows(new_pair_list_sorted)

# ステータス表示
print('----------------------------------------')
print(dt)
print('----------------------------------------')
print('new_pair_list_sorted: ' + str(new_pair_list_sorted))
print('----------------------------------------')

5. まとめ

Binanceの公式APIを使えば、比較的簡単に相場情報を取得して活用できるのです。

<このプログラムをさらに改造してできそうなこと>

  • csvに保存するのではなく、データベースに格納するように改造してみる
  • 取得した情報でローソクチャートなどのグラフを出力してみる
  • 取得した情報を機械学習、ディープラーニングで活用する

…などなど、色々活用できるのではないでしょうか。

次回は、Binance公式APIを活用して実際に通貨を売買させる方法について扱ってみたいと思います!