前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。
前回の記事で作ったBotの問題点を解消したコードを作りました。
簡単に言うと「価格が20%以上変動したタイミングを見て注文を出す」ように条件付けしています。
また、「すでに注文を出している時には新たに注文を出さない」ようにしています。
サーキットブレーカーBot2
ChatGPTに出した指示は以下の3つ。
上記のコードでは、現在の価格に反応して注文を発生させてしまうのではないか。 価格が20%変動した時に買い注文や売り注文を出すコードにするにはどうすれば良いか。
「price_change_ratioが20%以上の時」に条件変更しなさい。
上記のコードで買い注文か売り注文を持っている時は、新たに買いと売りの注文を出さないようにしたい。どうすれば良いか。
作成されたのが以下のコードです。
import ccxt
import datetime
import time
# APIキーとAPIシークレットを直接設定
api_key = 'Your API KEY'
api_secret = 'Your API SECRET'
bitflyer = ccxt.bitflyer({
'apiKey': api_key,
'secret': api_secret,
})
symbol = 'FX_BTC_JPY'
def get_current_price():
ticker = bitflyer.fetch_ticker(symbol)
return ticker['last']
def close_order(order_id):
try:
bitflyer.cancel_order(order_id, symbol)
print(f"注文 {order_id} が手仕舞いされました。")
except ccxt.NetworkError as e:
print(f"手仕舞いエラー(ネットワークエラー): {str(e)}")
except ccxt.ExchangeError as e:
print(f"手仕舞いエラー(取引所エラー): {str(e)}")
except Exception as e:
print(f"手仕舞いエラー(その他のエラー): {str(e)}")
# メインのループ処理
buy_order = None
sell_order = None
while True:
try:
closest_diff = 1000000000
closest_num = 0
# 現在のUNIXタイムスタンプを取得
current_time = datetime.datetime.now().timestamp()
# 10分前のUNIXタイムスタンプを計算
ten_minutes_ago = current_time - 600
# 約定履歴を取得
trades = bitflyer.fetch_trades(symbol, limit=500)
for i in range(len(trades)):
time_diff = (trades[i]["timestamp"] - ten_minutes_ago * 1000) / 1000
if abs(time_diff) < closest_diff:
closest_diff = abs(time_diff)
closest_num = i
past_price = trades[closest_num]["price"]
current_price = get_current_price()
# 注文を作成する条件: 過去の価格と現在の価格が20%以上の変動率を超えた場合に注文を作成する
price_change_ratio = (current_price - past_price) / past_price
if abs(price_change_ratio) > 0.2: # 例: 価格変動率が20%以上の場合
# 既に買い注文が存在しない場合に注文を作成
if buy_order is None:
buy_price = int(current_price * 0.8)
buy_order = bitflyer.create_order(symbol, "limit", "buy", 0.01, buy_price)
print("買い注文が発注されました.")
# 既に売り注文が存在しない場合に注文を作成
if sell_order is None:
sell_price = int(current_price * 1.2)
sell_order = bitflyer.create_order(symbol, "limit", "sell", 0.01, sell_price)
print("売り注文が発注されました.")
while True:
time.sleep(5) # 注文が発注されてから手仕舞いを試みるまでの待機時間
current_price = get_current_price()
# 利益率が一定の閾値を超えた場合に手仕舞いを試みる
if (current_price - past_price) / past_price > 0.15: # 例: 利益率がX%以上の場合
close_order(buy_order['id'])
close_order(sell_order['id'])
break # 手仕舞いが成功したらループを抜ける
except ccxt.NetworkError as e:
print(f"ネットワークエラーが発生しました: {str(e)}")
time.sleep(5)
except ccxt.ExchangeError as e:
print(f"取引所エラーが発生しました: {str(e)}")
# 取引所エラーの場合、エラーメッセージを表示
print(f"取引所エラーメッセージ: {e}")
time.sleep(5)
except Exception as e:
print(f"予期せぬエラーが発生しました: {str(e)}")
time.sleep(5)
このコードを実行しても、現在の相場では直ちに注文が出ることはありませんでした。
ひとまず、条件分岐については成功したと言って良いでしょう。
ただ、実際に稼働させる際は、変動率20%まで粘らなくても良いのかもしれません。
設定してある数値price_change_ratioを19%程度に設定しておくことで、早めの注文を出すということもできそうです。
また、手仕舞いの条件も20%全てが戻った時ではなく、15%に設定して利益を出しやすくしています。
サーキットブレーカーは発生タイミングが読めないため、手仕舞いまで確実にBotに行わせるのが良いと思います。
この辺りはリスク要因にもなるため、慎重に試していこうと思います。
まとめ
注文を出す時と手仕舞いの条件分岐を設定しました。
実際に稼働させて、効果を検証していきます。
この調子でコツコツと学習を進めていきます。