- 「ビットコイン、イーサリアム等、仮想通貨の自動売買システムを作りたい!」
- 「売買の凄いアイデアを持っているけど、会社員だし、ずっとチャートを見てるのは無理・・・」
- 「人工知能による、自動売買システムを作りたい!(近未来的でかっこいい!)」
本記事は、そのような方を対象にしています。
本記事にて、ご紹介するのは、以下の2点となります。
- bitFlyer APIを使用に当たって、事前準備するもの
- bitFlyer APIの使い方(Pythonコードのご紹介)
本記事は、Python初心者 以上の方を、対象にしています。
(Python入門レベルの方でも、少し勉強すれば理解できるよう、わかりやいコードを心がけました。)
また本記事では、bitFlyerが公開しているAPIのみを使ったコードを、ご紹介します。
(第3者が作った、ラッパーライブラリ等は、使用しないようにしました。)
お金の処理なので、信頼性があるコードのみ、使いたいと思ったからです。(そのライブラリがNGとか、決してそういう訳では、ございません。)
bitFlyerでの、事前準備
「API」を使用するために、事前準備するものを 2つ ご紹介します。
1、bitFlyerの口座開設
本取引所の主な特徴ですが、
- 資本力が高い(三井住友銀行グループのSMBCベンチャーキャピタル、みずほキャピタル 等々の大手企業から出資されている)
- 国内最大級の仮想通貨取引所(ビットコイン取引量 日本一)
「※ Bitcoin 日本語情報サイト調べ。国内暗号資産交換業者における 2021 年の年間出来高(差金決済/先物取引を含む)」 - セキュリティーが最高評価(※ Sqreen 社調べ。2018年1月発表、世界140の仮想通貨取引所を対象に調査。)
- 初心者に優しい画面設計、「bitWire」というメールアドレスだけで、ビットコインが送れるサービス
になります。
口座開設したいと思った方は、以下より申し込みできます。(bitFlyerの公式サイトに遷移します。)
以降の章からは、口座開設した前提での記事となっていますが、開設されていない方でも、十分に理解できる内容となっています。
口座開設の判断は、本記事を読まれてからでも、遅くないと思います。
2、API通信に必要な、「認証キー」情報を取得する。
API通信をするためには、
- 「API Key」
- 「API Secret」
を取得する必要があります。
「API Key」、「API Secret」情報は、絶対に人に漏らさないようにして下さい。
万が一、人に漏れた場合は、「作り直し」て下さい。
「認証キー」の取得手順
次の4つの手順で、「認証キー」を取得する事ができます。
① TOPページから、「bitFlyer Lightning」を選択
② 「bitFlyer Lightning」のサイトで、下記をクリック
③ ウインドウが出てくるので、「API」をクリック
④ 出現したウインドウより「新しいAPIキーを追加」をクリック
「新しいAPIキーを追加」をクリックすると、新しいポップアップが出てきます。
「全てチェック」にして、「OK」ボタンをクリックして下さい。
「認証キー」が作られます。
この「認証キー」は、プログラムにて使用します。大切に保管して下さい。
「認証キー」は、「API Key」「API Secret」の2つがあります。
両方必要なので、大切に保管して下さい。
bitFlyer APIを使ったコードの紹介
下記の順番で、ご紹介いたします。
bitFlyer 公式APIの仕様は、こちら(公式サイトに遷移)になります。
「わかりやすさ優先」という事で、「オブジェクト」は使用せず、「関数」のみのコードでご紹介しています。
口座の残高取得
bitFlyerの口座に、残高がいくらあるか、取得するコードになります。
下記コード中で出現する、それぞれの変数を
- settings.api_key → bitFlyerサイトより取得した、「API key」
- settings.api_secret → bitFlyerサイトより取得した、「API Secret」
で、置き換えて下さい。
setting.pyを別途作成し、機密情報はそこに入れておくのが、いいと思います。
下記コードになります。
api_key = **********
api_secret = *******************
本記事で紹介するコードでも、この方式を採用しています。
——-更に参考———–
更に優れているのは、「setting.ini」 ファイルを作って、configparserを使って、settings.pyに読込む方式です。
そしてファイルアクセス権限を設定すれば、セキュリティーの点でも、優れています。
その他にも、環境変数を使ったりする方法等があります。
ご検討頂ければと思います。
コード(口座の残高取得)
HTTP通信ライブラリとして、「requests」を使用しています。
事前にインストールをお願いします。
pip install requests
下記コードの get_balance()を呼ぶと、残高が取得できます。
(def header( )部分は、後ほど、ご紹介しています。)
import hashlib
import hmac
import requests
import time
def header(method: str, endpoint: str, body: str) -> dict:
timestamp = str(time.time())
if body == '':
message = timestamp + method + endpoint
else:
message = timestamp + method + endpoint + body
signature = hmac.new(settings.api_secret.encode('utf-8'), message.encode('utf-8'),
digestmod=hashlib.sha256).hexdigest()
headers = {
'Content-Type': 'application/json',
'ACCESS-KEY': settings.api_key,
'ACCESS-TIMESTAMP': timestamp,
'ACCESS-SIGN': signature
}
return headers
def get_balance():
base_url = 'https://api.bitflyer.com'
endpoint = '/v1/me/getbalance'
headers = header('GET', endpoint=endpoint, body='')
response = requests.get(base_url + endpoint, headers=headers)
return response.json()
requestsコマンドを使う際は、try〜except を使って、例外処理をするようにして下さい。
ここでは、分かりやすさ優先で、あえて記載せずに、ご紹介しています。
実行結果
上記コードの、get_balance()を実行した結果です。
JSONで返ってきたものを、辞書型に変換しています。(response.json()の部分です。)
bitFlyerが扱っている、アルトコイン全体の残高が返ってきます。
# **** → 実際には、数字が入っています。
[{'currency_code': 'JPY', 'amount': ******, 'available': ******},
{'currency_code': 'BTC', 'amount': ******, 'available': ******},
{'currency_code': 'BCH', 'amount': 0.0, 'available': 0.0},
{'currency_code': 'ETH', 'amount': ******, 'available': ******},
{'currency_code': 'ETC', 'amount': 0.0, 'available': 0.0},
{'currency_code': 'LTC', 'amount': ******, 'available': ******},
{'currency_code': 'MONA', 'amount': 0.0, 'available': 0.0},
{'currency_code': 'LSK', 'amount': ******, 'available': ******},
{'currency_code': 'XRP', 'amount': ******, 'available': ******},
{'currency_code': 'BAT', 'amount': ******, 'available': ******},
{'currency_code': 'XLM', 'amount': ******, 'available': ******},
{'currency_code': 'XEM', 'amount': ******, 'available': ******},
{'currency_code': 'XTZ', 'amount': ******, 'available': ******},
{'currency_code': 'DOT', 'amount': 0.0, 'available': 0.0}]
amountは「資産残高」、availableは「使用可能残高」になります。
(指値発注時など、一部の資産が拘束されるため、「amount」 と 「available」は異なる場合があります。)
上記JSON中の、****は実際は数字が返ってきます。(筆者の残高情報が入っているため、*に置き換えました・・・)
コード中の認証部分の説明
コード中の、def header(・・・ の部分になります。
bitFlyerの公式APIサイトに以下の説明が書かれています。
以下の情報を HTTP リクエストヘッダに含めます。
ACCESS-KEY
: 開発者ページで発行した API keyACCESS-TIMESTAMP
: リクエスト時の Unix TimestampACCESS-SIGN
: 以下の方法でリクエストごとに生成した署名
ACCESS-SIGN
は、ACCESS-TIMESTAMP, HTTP メソッド, リクエストのパス, リクエストボディ を文字列として連結したものを、 API secret で HMAC-SHA256 署名を行った結果です。
公式のページでは、Node.jsで書かれたコードが紹介されていましたが、それをPythonに直しました。
この部分、よく分からなくても、このままコピペで大丈夫です。
(今回のAPI使用に関しては、これで事足ります。)
ビットコイン価格の取得(1回のみ)
コード(ビットコイン価格の取得)
ビットコインの事例で、価格取得方法をご紹介します。
イーサリアムの場合は、コード中の変数を「product_code = ‘eth_jpy’」に変更して下さい。
def get_ticker():
base_url = 'https://api.bitflyer.com'
endpoint = '/v1/ticker'
product_code = 'btc_jpy' # ビットコインの場合
# product_code = 'eth_jpy' # イーサリアムの場合
response = requests.get(base_url + endpoint, params={"product_code": product_code})
return response.json()
実行結果
上記コードの、get_ticker()を実行した結果です。
同じく、JSONで返ってきたものを、辞書型に変換しています。
返ってくる値の各意味を、注釈にて記述しておきました。
{'product_code': 'BTC_JPY',
'state': 'RUNNING',
'timestamp': '2021-08-14T03:10:19.72', # UTCで表示
'tick_id': 16261706,
'best_bid': 5211026.0, # 最高買価格
'best_ask': 5213834.0, # 最低売価格
'best_bid_size': 0.02, # 最高買価格数
'best_ask_size': 0.1235, # 最低売価格数
'total_bid_depth': 840.49197604, # 売り注文総数
'total_ask_depth': 469.6806732, # 買い注文総数
'market_bid_size': 0.0, # 板寄せ時の売りの成行注文量
'market_ask_size': 0.0, # 板寄せ時の買いの成行注文量
'ltp': 5213834.0, # 最終取引価格
'volume': 11186.61364203, # 24hの取引量
'volume_by_product': 3620.19260028 # 価格ごとの出来高
}
発注する
単純な指値注文 (LIMIT)、成り行き注文 (MARKET)のみを対象としたコードをご紹介します。
それ以外は、bitFlyerさんのAPIでは、「親注文」という特殊注文扱いになります。下記記事にて、ご紹介しています。
コード(発注)
ビットコインの事例です。
イーサリアムの場合は、コード中の6行目を「product_code = ‘eth_jpy’」に変更して下さい。
また、口座の残高で紹介した、header関数「header()」を、使用しています。
def order():
base_url = 'https://api.bitflyer.com'
endpoint = "/v1/me/sendchildorder"
body = {
"product_code": 'btc_jpy', # ビットコイン(日本円)
"child_order_type": 'LIMIT', # 指値。成行きの場合は、MARKET
"side": 'BUY', # 「買い」注文
"price": 3000000, # 価格指定
"size": 0.001, # 注文数量
"minute_to_expire": 1000, # 期限切れまでの時間(分)
"time_in_force": 'GTC' # GTC発注
}
body = json.dumps(body)
headers = header('POST', endpoint=endpoint, body=body)
response = requests.post(base_url + endpoint, data=body, headers=headers)
return response.json()
実行結果
上記の order()を呼んだ結果です。
同じく、JSONで返ってきたものを、辞書型に変換しています。
下記の「API受付ID」は、キャンセル処理する際に、使用します。
{
'child_order_acceptance_id': 'JRF20210323-115602-225510' # 発注時の「API受付ID」
}
注文の一覧を確認する
コード(注文の一覧を確認する)
ビットコインを事例にして、注文した一覧を取得するコードをご紹介します。
イーサリアムの場合は、「product_code = ‘eth_jpy’」に変更して下さい。
また、口座の残高で紹介した、header関数「header()」を、使用しています。
def list_child_order():
base_url = 'https://api.bitflyer.com'
endpoint = '/v1/me/getchildorders'
product_code = 'btc_jpy' # ビットコイン価格(日本円)
params = {
"product_code": product_code
}
endpoint_for_header = endpoint + '?'
for k, v in params.items():
endpoint_for_header += k + '=' + v
endpoint_for_header += '&'
endpoint_for_header = endpoint_for_header[:-1]
headers = header('GET', endpoint=endpoint_for_header, body='')
response = requests.get(base_url + endpoint, headers=headers, params=params)
return response.json()
実行結果
上記の list_child_order()を実行した結果です。
同じく、JSONで返ってきたものを、辞書型に変換しています。
返ってくる値の意味を、注釈で記述しておきました。
[{'id': 2456291909,
'child_order_id': 'JOR20210323-115602-043106', # 注文する時に発行される一意なID
'product_code': 'BTC_JPY',
'side': 'SELL', # 「売り」で発注
'child_order_type': 'MARKET', # 「成り行き」発注
'price': 0.0,
'average_price': 5895493.0, # 「約定時」の平均価格
'size': 0.023, # 約定した量
'child_order_state': 'COMPLETED', # 取引完了の案件 オープンの注文があれば active になる。
'expire_date': '2021-04-22T11:56:02',
'child_order_date': '2021-03-23T11:56:02',
'child_order_acceptance_id': 'JRF20210323-115602-225510', # 発注時の 「API受付ID」
'outstanding_size': 0.0,
'cancel_size': 0.0,
'executed_size': 0.023,
'total_commission': 3.45e-05},
# 以下、2個目の発注内容が続く・・・
]
注文をキャンセル処理をする
注文をキャンセル処理をする(未約定の場合のみ)
特定のオーターをキャンセルする場合
コード中の「child_order_acceptance_id」は、発注時に発行された「API受付ID」に置き換えて下さい。
(このコード中の、「JRF20150707-033333-099999″」という番号で表示されている箇所を変更して下さい。)
また、口座の残高で紹介した、header関数「header()」を、使用しています。
キャンセルに成功すれば、ステータスコードとして、200 が返ってきます。
import json
def order_cancel(self):
base_url = 'https://api.bitflyer.com'
endpoint = "/v1/me/cancelchildorder"
body = {
"product_code": 'btc_jpy',
"child_order_acceptance_id": "JRF20150707-033333-099999"
}
body = json.dumps(body)
headers = self.header('POST', endpoint=endpoint, body=body)
response = requests.post(base_url + endpoint, data=body, headers=headers)
return response.status_code
全オーダーのキャンセルする場合
import json
def all_order_cancel():
base_url = 'https://api.bitflyer.com'
endpoint = "/v1/me/cancelallchildorders"
body = {
"product_code": 'btc_jpy'
}
body = json.dumps(body)
headers = self.header('POST', endpoint=endpoint, body=body)
response = requests.post(base_url + endpoint, data=body, headers=headers)
return response.status_code
実行結果
正しく処理された場合は、ステータスコードの「200」が返ってきます。
リアルタイムでの、ビットコイン価格を取得
価格変動があった場合、リアルタイムに価格情報を取得するコードをご紹介します。
「WebSocket」を使用しています。
事前にインストールが必要です。
pip install websocket-client
コード(リアルタイムでの、ビットコイン価格を取得)
データが送られてくると、下記コード中の、「on_message」変数に代入した「get_real_ticker_on_message」関数が呼ばれます。
import websocket
def get_realtime_ticker():
product_code = 'BTC_JPY' # 小文字NG
web_socket_url = 'wss://ws.lightstream.bitflyer.com/json-rpc'
channel = f'lightning_ticker_{product_code}'
ws = websocket.WebSocketApp(web_socket_url,
on_message=get_real_ticker_on_message,
on_open=lambda wss: wss.send(json.dumps({'method': 'subscribe',
'params': {'channel': channel}}))
)
try:
ws.run_forever()
except Exception as e:
# ロギング処理するとか
raise
def get_real_ticker_on_message(ws, message):
# WebsocketでJSON-RPCから情報が来た時の処理
message = json.loads(message)['params']
message = message.get('message')
print(message)
- 「on_open」変数 → websocket 実行前に実施
- その他、エラー発生時、websocket 終了時に、実行する関数登録も可能です。
実行結果
上記コードの「get_real_ticker_on_message」関数中の、message変数の中身です。
下記の情報がリアルタイムで送られてきます。
{'product_code': 'BTC_JPY',
'state': 'RUNNING',
'timestamp': '2021-08-15T02:52:02.6888776Z', # UTCで表示
'tick_id': 17356610,
'best_bid': 5179796.0, # 最高買価格
'best_ask': 5182499.0, # 最低売価格
'best_bid_size': 0.2568, # 最高買価格数
'best_ask_size': 0.47, # 最低売価格数
'total_bid_depth': 852.46014501, # 売り注文総数
'total_ask_depth': 593.72290046, # 買い注文総数
'market_bid_size': 0.0, # 板寄せ時の売りの成行注文量
'market_ask_size': 0.0, # 板寄せ時の買いの成行注文量
'ltp': 5179792.0, # 最終取引価格
'volume': 3364.02532087, # 24hの取引量
'volume_by_product': 3364.02532087 # 価格ごとの出来高
}
実際の売買システムとしては、
- この取得した情報を分析し、売買戦略に基づき、売買処理をする
というコードになります。
素晴らしい売買戦略を見つけられれば、お金という観点では、「人生の勝ち」が決まったようなものです(笑)
分析手法として、
- テクニカル分析
が候補として挙がると思います。
下記記事が参考になるかと思います。併せてどうぞ。
最後に
本記事を読んで、「私でも作れそう」と思って頂けたら、幸いです。
「よく分からなかった・・・」と思われた方でも、
最初のうちは、本記事のコードを「コピペ」して使っていく中で、段々と理解できていくと思います。
冒頭でもお話しましたが、「bitFlyer」は他社にない強みがあってお薦めです。
口座作成費用、口座維持費用は無料ですし、自動売買取引のAPIデビューにはオススメです。
(金額を思いっきり少なくして取引すれば、数千円位から取引可能です。)
申し込みは下記リンクより可能です。(bitFlyerの公式サイトに遷移します。)
それではまた、お会いしましょう!