どうもふうやです。
最近忙しくてブログを書いたり、Botを動かしたり出来てませんでした。
BitFlyerのBotの方はというと自分が利用していたものは完全に非公式API化しております。
いずれはBitFlyerの非公式APIも流行るだろうという考えから、もうここで自分が利用している非公式APIを全て無料でソースコードを公開させていただきます。
目次
BitFlyerの非公式APIで無制限に使いまわそう。
※自分が利用している非公式APIを完全に無料でソースコードを全公開させていただきますが、将来的に利用できなくなったりアカウントがBANされる可能性が懸念されますが、そういった場合であっても責任を取りかねませんので予めご了承下さい。
非公式APIの特徴
- 遅延が公式APIより少ない
- API制限無く利用できる
非公式APIを利用する前の下準備
非公式APIを利用するには予めcookieを取得する必要があります。
それをヘッドレスブラウザ経由で取得後にメインループ開始という流れでBotを動かすイメージだと思って下さい!
また環境によってヘッドレスブラウザの場所等が違うと思いますので、そちらの方は適宜対処してください!
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
#ヘッドレスブラウザを起動
options = Options()
options.binary_location = '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary'
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
browser = webdriver.Chrome(chrome_options=options)
#bitFlyer Lightningにアクセス
url = "https://lightning.bitflyer.jp/"
browser.get(url)
# メールアドレスとパスワードを入力
e = browser.find_element_by_css_selector("#LoginId")
e.send_keys("ログインメールアドレス")
e = browser.find_element_by_css_selector("input[type=password]")
e.send_keys("ログインパスワード")
#ログインボタンを押す
e = browser.find_element_by_css_selector("#login_btn").click()
#cookieの取得
cookies = dict(
_gid = browser.get_cookie("_gid")["value"],
_gat = browser.get_cookie("_gat")["value"],
_ga = browser.get_cookie("_ga")["value"],
api_session_v2 = browser.get_cookie("api_session_v2")["value"],
NET_SessionId = browser.get_cookie("ASP.NET_SessionId")["value"],
ai_user = browser.get_cookie("ai_user")["value"],
__RequestVerificationToken = browser.get_cookie("__RequestVerificationToken")["value"],
__cfduid = browser.get_cookie("__cfduid")["value"],
_tdim = browser.get_cookie("_tdim")["value"],
ai_session = browser.get_cookie("ai_session")["value"]
)
これで下準備のcookieの取得は完了です。
header情報も非公式APIにPOSTする際に必要になるため、こちらも書いておきます!
headers = {
"accept":"*/*",
"accept-encoding":"gzip, deflate, br",
"accept-language":"ja,en;q=0.9",
"content-length":"234",
"content-type":"application/json; charset=utf-8",
"origin":"https://lightning.bitflyer.jp",
"referer":"https://lightning.bitflyer.jp/trade/",
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
"x-requested-with":"XMLHttpRequest"
}
各種jsonのレスポンスを整形する場合
参考 JSON Pretty Linter Ver3Syncerこちらのサイトで整形すると良いでしょう!
必要なライブラリ
import requests
import datetime
import random
import json
板情報を取得する(URLに直アクセス可)
#板情報を取得
def get_board() :
url = "https://lightning.bitflyer.com/api/trade/tickerdata?product_code=FX_BTC_JPY&v=1"
response = requests.get(url)
res = response.json()
return res[0]["board"]
板情報はcookieやヘッダー無しで取得できるため、getにてそのまま取得しています。
“product_code”を”FX_BTC_JPY”にしておりますが、ここを変更することで他の銘柄の板情報が取得できます。
またこちらの関数のレスポンスは公式APIでgetboardした時と同様です。
LTPを取得する(URLに直アクセス可)
#FXのLTPを取得
def get_ltp() :
url = "https://lightning.bitflyer.com/api/trade/ticker/all?v=1"
response = requests.get(url)
res = response.json()
return res[1]["ticker"]["LTP"]
こちらの関数では”product_code”が”FX_BTC_JPY”のLTPを取得しています。
またgetで取得していますのでURLに直アクセスして利用する情報を簡単に見つけることが出来ます。
return部分の[1]を変更すると各種銘柄のLTPを取得できます。
各種銘柄のアクセス方法
- res[0] = “BTC_JPY”
- res[1] = “FX_BTC_JPY”
- res[2] = “ETH_BTC”
- res[3] = “BCH_BTC”
- res[4] = “BTC_USD”
- res[5] = “BTC_EUR”
- res[6] = “BTCJPY28DEC2018”
- res[7] = “BTCJPY05OCT2018”
- res[8] = “BTCJPY12OCT2018”
best_askとbest_bidを取得する
def best() :
url = "https://lightning.bitflyer.com/api/trade/ticker/all?v=1"
response = requests.get(url)
res = response.json()
return [int(res[1]["ticker"]["best_ask"]),int(res[1]["ticker"]["best_bid"])]
こちらの関数では先程と同じURLに対して、getさせbest_askとbest_bidを取得しています。
返り値はint型にしております。
また先程と同様に返り値の”res[数字]”の部分を変更することによって各種銘柄のbest_askとbest_bidを取得することが出来ます。
指値注文をする
#指値で注文する
def order_limit(price,side,size) :
url = "https://lightning.bitflyer.jp/api/trade/sendorder"
today = datetime.datetime.now()
data = {
"product_code":product_code,
"ord_type":"LIMIT",
"price": price,
"side" : side,
"size": size,
"minuteToExpire":43200,
"time_in_force":"GTC",
"order_ref_id":"JRF"+today.strftime('%Y%m%d-%H%M%S')+"-"+str(random.randint(100000,999999)),
"is_check":False,
"lang":"ja"
}
requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
“ord_type” が”LIMIT”なのは指値を表しています。
他にも成行とTRAIL注文も紹介するので、ord_typeにも注目しつつ参考にして下さい。
成行注文をする
#成行で注文する
def order_market(side) :
url = "https://lightning.bitflyer.jp/api/trade/sendorder"
today = datetime.datetime.now()
data = {
"product_code":product_code,
"ord_type":"MARKET",
"price": 0,
"side" : side,
"size": size,
"minuteToExpire":43200,
"time_in_force":"GTC",
"order_ref_id":"JRF"+today.strftime('%Y%m%d-%H%M%S')+"-"+str(random.randint(100000,999999)),
"is_check":False,
"lang":"ja"
}
requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
成行注文の注意点としてはpriceを0に置くことです。
TRAILを注文する
#TRAIL注文する
def order_trail(side) :
url = "https://lightning.bitflyer.com/api/trade/sendtrailorder"
today = datetime.datetime.now()
data = {
"product_code":product_code,
"ord_type":"TRAIL",
"side" : side,
"price": 0,
"size": size,
"minuteToExpire":43200,
"offset":offset,
"time_in_force":"GTC",
"order_ref_id":"JRF"+today.strftime('%Y%m%d-%H%M%S')+"-"+str(random.randint(100000,999999)),
"is_check":False,
"lang":"ja"
}
res = requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
return res.json()
TRAIL注文する場合もpriceは0でoffsetの数値の値が必要です。
IFD注文をする
#IFD注文を行う
def order_ifd(side,other_side,size,price) :
url = "https://lightning.bitflyer.com/api/trade/sendIFDorder"
today = datetime.datetime.now()
data = {
"product_code":product_code,
"first":{
"product_code":product_code,
"ord_type":"MARKET",
"side":side,
"price":0,
"size":size,
"minuteToExpire":43200,
},
"second":{
"product_code":product_code,
"ord_type":"LIMIT",
"side":other_side,
"price":price,
"size":size,
"minuteToExpire":43200,
},
"minuteToExpire":43200,
"time_in_force":"GTC",
"is_check":False,
"order_ref_id":"JRF"+today.strftime('%Y%m%d-%H%M%S')+"-"+str(random.randint(100000,999999)),
"lang":"ja"
}
requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
IFD注文を行う場合は少し応用が必要です。
firstとsecondの意味はお分かりいただけると思いますが、その中身は注文方法によって変えなければいけません。
必ず、”product_code”と”ord_type”、”side”、”price”、”size”は記述する必要があり、TRAIL注文の場合は”offset”の値が必須です。
IFDOCO注文をする
#IFDOCO注文を行う
def order_ifd(side,other_side,size,second_price,third_price) :
url = "https://lightning.bitflyer.com/api/trade/sendIFDOCOorder"
today = datetime.datetime.now()
data = {
"product_code":product_code,
"first":{
"product_code":product_code,
"ord_type":"MARKET",
"side":side,
"price":0,
"size":size,
"minuteToExpire":43200,
},
"second":{
"product_code":product_code,
"ord_type":"LIMIT",
"side":other_side,
"price":second_price,
"size":size,
"minuteToExpire":43200,
},
"third":{
"product_code":product_code,
"ord_type":"LIMIT",
"side":other_side,
"price":third_price,
"size":size,
"minuteToExpire":43200,
},
"minuteToExpire":43200,
"time_in_force":"GTC",
"is_check":False,
"order_ref_id":"JRF"+today.strftime('%Y%m%d-%H%M%S')+"-"+str(random.randint(100000,999999)),
"lang":"ja"
}
requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
こちらのIFDOCO注文もIFD注文と同じ注意事項に従って利用して下さい。
注文状況を調べる
#注文状況を調べる
def my_board() :
url = "https://lightning.bitflyer.com/api/trade/getMyBoardOrders"
data = {
"product_code": product_code,
"lang": "ja"
}
res = requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
return res.json()
注文をキャンセルする
def order_cancel(order_id) :
url = "https://lightning.bitflyer.com/api/trade/cancelallorder"
data = {
"product_code":product_code,
"order_id":order_id,
"lang":"ja"
}
response = requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
res = response.json()
return res
全ての注文をキャンセルする
#全ての注文をキャンセルする
def order_all_cancel() :
url = "https://lightning.bitflyer.com/api/trade/cancelallorder"
data = {
"product_code":product_code,
"lang":"ja"
}
requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
証拠金残高を取得する
#証拠金残高を取得する
def get_colla() :
url = "https://lightning.bitflyer.com/api/trade/getmyCollateral"
today = datetime.datetime.now()
data = {
"product_code":product_code,
"lang":"ja"
}
response = requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
res = response.json()
return res["data"]["withdrawable_collateral"]
現在の損益状況を取得する
#現在の損益状況を取得する
def get_open_collateral() :
url = "https://lightning.bitflyer.com/api/trade/getmyCollateral"
data = {
"lang": "ja",
"product_code": product_code
}
response = requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
res = response.json()
return int(res["data"]["margin_status"]["Details"]["FX_BTC_JPY"]["OpenPositionPnl"])
建玉状況を取得する
#建玉の状況を取得する
def get_position_side() :
url ="https://lightning.bitflyer.com/api/trade/getmyCollateral"
data = {
"product_code": product_code,
"lang": "ja"
}
res = requests.post(url, data=json.dumps(data),cookies = cookies,headers = headers)
return res.json()["data"]
建玉の注文方向を知る際は、返り値を”res.json()[“data”][“position_side”]”にします。
まとめ
Chromeの検証ツールのネットワークとにらめっこしたのですが、公式APIのget_healthを非公式APIで取得できないことが悔しかったです笑笑
ここに”health”の項目がありますが、いつもnullになっているからです笑
ありがとうございました!!
コメントを残す