BitflyerFXからAPIで現在のポジションの建値やサイズを取得する方法を解説します。具体的な使い道として以下のような場面を想定しています。
(1)BOTを再稼働させたときにポジション情報を取得する
(2)注文拒否や二重約定などでBOTがポジションを見失った場合
(3)ループのたびにポジション情報を取得する仕様にする場合
前提
CCXTライブラリを使います。
・CCXTライブラリのGithubページ
・CCXTライブラリって何?を解説
・CCXTライブラリで取引所のAPIを直接使う方法
Pythonコード
import ccxt bitflyer = ccxt.bitflyer() bitflyer.apiKey = '' bitflyer.secret = '' def check_bf_positions(): while True: try: size = [] price = [] positions = bitflyer.private_get_getpositions( params = { "product_code" : "FX_BTC_JPY" }) if not positions: print("現在ポジションは存在しません") return 0,0,None for pos in positions: size.append( pos["size"] ) price.append( pos["price"] ) side = pos["side"] # 平均建値を計算する average_price = round(sum( price[i] * size[i] for i in range(len(price)) ) / sum(size)) sum_size = round(sum(size),2) print("保有中の建玉:合計{}つ\n平均建値:{}円\n合計サイズ:{}BTC\n方向:{}".format(len(price),average_price,sum_size,side)) # 価格・サイズ・方向を返す return average_price,sum_size,side except ccxt.BaseError as e: print("BitflyerのAPIで問題発生 : ",e) print("20秒待機してやり直します") time.sleep(20) # 実行処理 price,size,side = check_bf_positions()
保有中の建玉の価格とサイズ、エントリーの方向の3つをセットで返す関数です。複数のポジションを保有している場合は、平均建値と合計サイズを計算して返します。
BitflyerFXでは両建てはできないので、方向(BUYかSELLか)は、複数ポジションのうち1つを参照すれば大丈夫です。そのため、最後に取得したポジションの方向を参照しています。
ポジションが存在しない場合
もしポジションが存在しなければ、price=0, size=0, side=None を返します。これらのいずれかを使えば、外部から以下のように「ポジション無し」を判定できます。
▽ ポジションの有無を判定したい場合
price,size,side = check_bf_positions() if size == 0: print("ポジションは存在しません")
BitflyerのAPI
BitflyerのAPIには、建玉の一覧を取得するAPI「GET /v1/me/getpositions」を、CCXTライブラリ経由で使用しています。
このAPIを使用すると、建玉の情報が配列で返ってきます。そのため、以下のような形式で情報にアクセスできます。
▽ 返り値を positions に入れた場合
positions[0] # 最初に取得したポジションの情報 positions[-1] # 最後に取得したポジションの情報 positions[0]["price"] # エントリー価格 positions[0]["side"] # エントリーの方向 positions[0]["size"] # ポジションのサイズ
いくつポジションを保有しているかわからない場合は、for文で回して全ての情報を取得します。
サイズ計算の注意点
合計サイズは、APIで取得した各建玉のサイズの合計値を計算しています。しかしpythonは足し算などの演算を2進法で計算するため、四捨五入しないと最終的な値がおかしくなることがあります。
具体例
例えば、以下のような3つの建玉がある場合、合計サイズは普通に計算すれば 0.21BTC になります。しかしpythonが2進法で足し算をすると、これは0.21 にならず、0.21000000000002 になってしまいます。
size1 = 0.11634476 size2 = 0.08175024 size3 = 0.011905 print(size1 + size2 + size3) #----- 実行結果 ------ 0.21000000000000002
そのため、合計サイズは四捨五入して規定の小数点以下に丸めておく必要があります。例えば、ご自身のBOTがすべての注文を小数点以下2桁で管理しているなら、小数点以下2桁で丸めれば大丈夫です。
これが上記コードの以下の箇所です。
sum_size = round(sum(size),2)
エラーになってしまいますので共有させて頂きます。
average_price = round(sum( price[i] * size[i] for i in range(len(price)) ) / sum(size))
TypeError: can’t multiply sequence by non-int of type ‘str’