【python】Bitflyer用マーチンゲール投資bot
詳細は下記ブログ内に記載しております。
pythonのソースコードは下記の通りです。
# coding: utf-8
import ccxt
import time
import math
# マーケット
product = "FX_BTC_JPY"
def order_limit(bitflyer,price,side,size):
try:
order_id = bitflyer.create_order(
symbol = 'FX_BTC_JPY', # 通貨ペア
type='limit', # 注文方法(limit: 指値, market: 成行)
side=side, # 注文の種類(buy: 買い, sell: 売り)
price=int(price), # 指値注文の価格
amount=str(size), # 注文数量
)
print("価格:",price,"数量:",size,side)
except:
print("注文エラー:","価格:",price,"数量:",size,side)
#print(order_id)
return
return order_id
bitflyer = ccxt.bitflyer()
list_price = []
isFirst = True
counts = 0
#--------------------------------設定項目--------------------------------------
spread = 100 #現在値・平均建玉からどれだけ離して指値を置くか
size = 0.01 #初期投資額 ビットコイン0.01枚
ordertime = 5#指値の確認間隔 指値が約定したかどうかを確認する時間(秒)
bitflyer.apiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"#bitflyerのapiを記載
bitflyer.secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"#bitflyerのapiを記載
#--------------------------------設定項目(ここまで)--------------------------------------
askordersize = size
bidordersize = size
openinterest=[[],[],[]]
interestprice = 0
interestsize = 0
Checkint = False
Checkopennum = 1
Checkorder = False
# メインループ
while True:
try:
orders = bitflyer.fetch_open_orders(
symbol = "BTC/JPY",
params = { "product_code" : "FX_BTC_JPY" })
#オープンオーダーが2つある時は注文が残っているので次のループへ
if len(orders) >1:
time.sleep(ordertime)
print("指値の数:",len(orders))
print("待機")
print("---------------------------------")
continue
if len(orders)>0:
for order in orders:
bitflyer.cancel_order(
symbol = "BTC/JPY",
id = order["id"],
params = { "product_code" : "FX_BTC_JPY" })
print("指値を更新します")
#①建玉を確認する
getposition = bitflyer.private_get_getpositions( params = { "product_code" : "FX_BTC_JPY" })
#※中身はこれ Checkside == ['BUY', 0.02, 419111.49999999994] [side,size,price]が格納されている
Checkside = [0,0,0]
#複数ポジションであってもsideはSELLかBUYの固定なので場合分けしなくても問題なし
if len(getposition)>0:
for Check in getposition:
Checkside[0] = Check["side"]
Checkside[1] = Checkside[1] + Check["size"]
Checkside[2] = Checkside[2] + Check["size"] * Check["price"]
#平均建値を計算
Checkside[2] = Checkside[2]/Checkside[1]
Checkint = True
Checkside[1] = round(float(Checkside[1]),4)
print(Checkside[1])
#ポジションを持っているか判定
if Checkint == True:
Checkopennum = int(math.log2(abs(Checkside[1]/size))+1)
if Checkside[0] == "BUY":
bidordersize = round(Checkside[1]*2,4)
#平均建玉を解消する分のロット数
askordersize = round(Checkside[1]+size,4)
else:
bidordersize = round(Checkside[1]+size,4)
askordersize = round(Checkside[1]*2,4)
askprice = int(Checkside[2]) + spread * Checkopennum
bidprice = int(Checkside[2]) - spread * Checkopennum
else:
ticker = bitflyer.fetch_ticker('BTC/JPY', params = { "product_code" : "FX_BTC_JPY" })
nowprice = (ticker["info"]["best_ask"]+ticker["info"]["best_bid"])/2
askprice = nowprice + spread
bidprice = nowprice - spread
askordersize = size
bidordersize = size
#次回ループ用に初期化しておく
Checkint = False
order_limit(bitflyer,askprice,"SELL",askordersize)
order_limit(bitflyer,bidprice,"BUY",bidordersize)
Checkorder = False
print("---------------------------------")
time.sleep(ordertime)
except:
time.sleep(ordertime)
print("error")
ご利用の際はソースコード内の設定項目(下記文言の箇所)を変更してください。
#--------------------------------設定項目--------------------------------------
spread = 100 #現在値・平均建玉からどれだけ離して指値を置くか
size = 0.01 #初期投資額 ビットコイン0.01枚
ordertime = 5#指値の確認間隔 指値が約定したかどうかを確認する時間(秒)
bitflyer.apiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"#bitflyerのapiを記載
bitflyer.secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"#bitflyerのapiを記載
#--------------------------------設定項目(ここまで)--------------------------------------
※追記
初期実行時に、保有在庫を0にする処理と注文キャンセルを行う処理を実装しました。
設定項目内のフラグを使用することで実行できます。
初期化したくない場合は「IniFlag=False」をすれば初期化されません。その場合は上記のコードと同じ動作となります。
# coding: utf-8
import ccxt
import time
import math
# マーケット
product = "FX_BTC_JPY"
def order_market(bitflyer,side,size):
order_id = bitflyer.create_order(
symbol = 'FX_BTC_JPY', # 通貨ペア
type='market', # 注文方法(limit: 指値, market: 成行)
side=side, # 注文の種類(buy: 買い, sell: 売り)
amount=str(size), # 注文数量
)
print("初期化のため在庫処分","数量:",size,side)
return order_id
def order_limit(bitflyer,price,side,size):
try:
order_id = bitflyer.create_order(
symbol = 'FX_BTC_JPY', # 通貨ペア
type='limit', # 注文方法(limit: 指値, market: 成行)
side=side, # 注文の種類(buy: 買い, sell: 売り)
price=int(price), # 指値注文の価格
amount=str(size), # 注文数量
)
print("価格:",price,"数量:",size,side)
except:
print("注文エラー:","価格:",price,"数量:",size,side)
#print(order_id)
return
return order_id
bitflyer = ccxt.bitflyer()
list_price = []
isFirst = True
counts = 0
#--------------------------------設定項目--------------------------------------
spread = 100 #現在値・平均建玉からどれだけ離して指値を置くか
size = 0.01 #初期投資額 ビットコイン0.01枚
ordertime = 5#指値の確認間隔 指値が約定したかどうかを確認する時間(秒)
IniFlag = True #Trueの場合、実行時に在庫を抱えていた場合0にする
bitflyer.apiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"#bitflyerのapiを記載
bitflyer.secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"#bitflyerのapiを記載
#--------------------------------設定項目(ここまで)--------------------------------------
askordersize = size
bidordersize = size
openinterest=[[],[],[]]
interestprice = 0
interestsize = 0
Checkint = False
Checkopennum = 1
Checkorder = False
# メインループ
while True:
try:
orders = bitflyer.fetch_open_orders(
symbol = "BTC/JPY",
params = { "product_code" : "FX_BTC_JPY" })
#初期実行時に指値注文キャンセルと保有在庫を0にする
if IniFlag == True:
#エラーした時にループして繰り返す。最後にbreak文が入っているので、エラーを出さずにきちんと実行されれば一度だけ処理を行う構成になっている
while True:
try:
if len(orders)>0:
for order in orders:
bitflyer.cancel_order(
symbol = "BTC/JPY",
id = order["id"],
params = { "product_code" : "FX_BTC_JPY" })
#①建玉を確認する
getposition = bitflyer.private_get_getpositions( params = { "product_code" : "FX_BTC_JPY" })
#※中身はこれ Checkside == ['BUY', 0.02, 419111.49999999994] [side,size,price]が格納されている
Checkside = [0,0,0]
#複数ポジションであってもsideはSELLかBUYの固定なので場合分けしなくても問題なし
if len(getposition)>0:
for Check in getposition:
Checkside[0] = Check["side"]
Checkside[1] = Checkside[1] + Check["size"]
Checkside[2] = Checkside[2] + Check["size"] * Check["price"]
#平均建値を計算
Checkside[2] = Checkside[2]/Checkside[1]
Checkint = True
Checkside[1] = round(float(Checkside[1]),4)
if Checkint == True:
if Checkside[0] == "BUY":
order_market(bitflyer,"SELL",round(Checkside[1],4))
else:
order_market(bitflyer,"BUY",round(Checkside[1],4))
Checkint = False
#ここでwhile文を抜ける
break
except:
print("初期化失敗です。もう一度実行します")
time.sleep(3)
#ここでIniFlagをFalseにするので2週目以降のループでは
IniFlag = False
#オープンオーダーが2つある時は注文が残っているので次のループへ
if len(orders) >1:
time.sleep(ordertime)
print("指値の数:",len(orders))
print("待機")
print("---------------------------------")
continue
if len(orders)>0:
for order in orders:
bitflyer.cancel_order(
symbol = "BTC/JPY",
id = order["id"],
params = { "product_code" : "FX_BTC_JPY" })
print("指値を更新します")
#①建玉を確認する
getposition = bitflyer.private_get_getpositions( params = { "product_code" : "FX_BTC_JPY" })
#※中身はこれ Checkside == ['BUY', 0.02, 419111.49999999994] [side,size,price]が格納されている
Checkside = [0,0,0]
#複数ポジションであってもsideはSELLかBUYの固定なので場合分けしなくても問題なし
if len(getposition)>0:
for Check in getposition:
Checkside[0] = Check["side"]
Checkside[1] = Checkside[1] + Check["size"]
Checkside[2] = Checkside[2] + Check["size"] * Check["price"]
#平均建値を計算
Checkside[2] = Checkside[2]/Checkside[1]
Checkint = True
Checkside[1] = round(float(Checkside[1]),4)
print(Checkside[1])
#ポジションを持っているか判定
if Checkint == True:
Checkopennum = int(math.log2(abs(Checkside[1]/size))+1)
if Checkside[0] == "BUY":
bidordersize = round(Checkside[1]*2,4)
#平均建玉を解消する分のロット数
askordersize = round(Checkside[1]+size,4)
else:
bidordersize = round(Checkside[1]+size,4)
askordersize = round(Checkside[1]*2,4)
askprice = int(Checkside[2]) + spread * Checkopennum
bidprice = int(Checkside[2]) - spread * Checkopennum
else:
ticker = bitflyer.fetch_ticker('BTC/JPY', params = { "product_code" : "FX_BTC_JPY" })
nowprice = (ticker["info"]["best_ask"]+ticker["info"]["best_bid"])/2
askprice = nowprice + spread
bidprice = nowprice - spread
askordersize = size
bidordersize = size
#次回ループ用に初期化しておく
Checkint = False
order_limit(bitflyer,askprice,"SELL",askordersize)
order_limit(bitflyer,bidprice,"BUY",bidordersize)
Checkorder = False
print("---------------------------------")
time.sleep(ordertime)
except:
time.sleep(ordertime)
print("error")
※本noteまたは本botにより発生した如何なる損害に対しても一切の責任を負いません。