SFDbotを狩る・倒す python websocketでSFDbotの動きを疑似解析してみた コードあり
SFDbotによって負けがかさむだけでなく、不要なSFD徴収によって損失が膨らんでいる人も多いのではないでしょうか?
私もSFDによって余計な損失を受け、ダメージを受けた一人です。
tradingviewでpineスクリプトを使い、投資戦略をバックテストし、pythonで実行していたところ、なかなかの運用成績を上げていました。このまま大きく稼げると読んでいたところ、SFDによる波乱相場がスタートしました。稼ぎがすべてSFD徴収に消え、いつの間にやらマイナス収支。
乖離の瀬戸際のSFD取った取らないのあおりをモロに受けました。
早く6%に行くか4%以下に戻るかしてほしいのに、SFDbotの大暴れ相場が続いています。ビットフライヤーによるBANを匂わす発言も効果なく、1円バーガーと呼ばれる1円しか離れていないbest_bidとbest_askに大量の注文が並ぶ異常な板が続いています。
今後もSFDが発生するたびに、SFDbotによる同様の現象が生じると思われるので、個人的な覚書としてSFDbotの動きを模してみた。なお、現状SFDbotはBANされる可能性があるので、実稼働はしません。
また、SFDbotの動きが解析できた際には、SFD狩りbotを作成しようと思います。名前はSFDbotkillerとかSFDbot殺しとか。
SFDbotはリアルタイムAPIで動いている
SFDbotは超高速で板の上を這いまわっているのですが、注文状況などの情報はRealTimeAPIから取得していると思われます。
botによって取引所のtick情報や板情報を得る場合、HTTP APIとRealTimeAPIがあるようです。(私自身専門家ではないので詳しく知らない)HTTP APIは毎回の接続で認証作業を行い、さらに取引所のサーバーを使用するのでコスト制限があります。要するに、遅いし使用制限がある状態。
一方、RealTimeAPIは認証作業が最初の一度だけであり、垂れ流し情報を受け続ける状態になります。ラジオ放送を聞いているような状態です。一度接続してしまえば、無制限に高速で情報が流れてきます。
RealTimeAPIはwebsocketなどの使用が必要
RealTimeAPIは通常のAPIのようなリクエストとレスポンスの形式ではないので、少し複雑な書き方になります。
下記のコードを参考にしてください。
import websocket
import json
CHANNEL = "lightning_ticker_BTC_JPY"
CHANNEL2 = "lightning_ticker_FX_BTC_JPY"
def on_message(ws, message):
global SFD
global fx_price
global btc_price
message = json.loads(message)
if message["params"]["channel"] == CHANNEL:
btc_price = message["params"]["message"]["ltp"]
elif message["params"]["channel"] == CHANNEL2:
dt = message["params"]["message"]["timestamp"].replace('T',' ').replace('Z','')
fx_price = message["params"]["message"]["ltp"]
SFD = fx_price/btc_price * 100 - 100
if message["params"]["channel"] == CHANNEL2:
print("Time:{} BTC:{} BTC_FX:{} SFD:{}".format(dt, btc_price, fx_price, round(SFD,5)))
def on_open(ws):
ws.send(json.dumps({"method": "subscribe",
"params": {"channel": CHANNEL}}))
ws.send(json.dumps({"method": "subscribe",
"params": {"channel": CHANNEL2}}))
if __name__ == "__main__":
# note: reconnection handling needed.
ws = websocket.WebSocketApp("wss://ws.lightstream.bitflyer.com/json-rpc",
on_message=on_message, on_open=on_open)
ws.run_forever()
pip install websocket-client を実行して、websocketを入れておきます。
CHANNELを指定してon_openでリクエストを出し、on_messageでレスポンスを受け取ります。json形式で保存し、必要な要素を抜き出します。timeは9時間前の時間を表しており、timestrpやtimedeltaで日本時間に変えることもできるのですが、処理が重くなるので、そのままにしています。
SFDはBTC現物の最終約定価格(ltp)を使用して計算されているそうなので、BTCとBTC_FXの最終約定価格を取り出しました。
pythonで走らした結果はこんな感じ。
上記のコードを走らせると、図のような数値情報が流れてきます。
9:39:47.8754562まで、SFDは5%以上。
9:39:47.9223305から、SFDは5%以下になっています。
SFDbotはBTCの最終約定価格からBUYエントリーを計算する
SFDbotはBTC現物の最終約定価格から105%乖離した価格を計算し、BUYエントリーを撒いています。そこで、考えられるエントリー価格は以下の2つです。
パターンA : BTC現物最終約定価格 x 1.04999
最終約定価格から104.999%乖離した価格を計算してエントリーに使用している。
パターンB : BTC現物最終約定価格 x 1.05 - 1
105%の乖離価格を計算し、1円低い値でエントリーしている。
それぞれを上記のコードに詰め込み、一切のビットフライヤーのチャートと照らし合わせて検討してみました。
import websocket
import json
import math
CHANNEL = "lightning_ticker_BTC_JPY"
def on_message(ws, message):
global btc_price
message = json.loads(message)
if message["params"]["channel"] == CHANNEL:
btc_price = message["params"]["message"]["ltp"]
if message["params"]["channel"] == CHANNEL:
print("BTC_ltp:{} A:{} B:{}".format(int(btc_price), math.ceil(btc_price*1.04999), math.ceil(btc_price*1.05-1)))
def on_open(ws):
ws.send(json.dumps({"method": "subscribe",
"params": {"channel": CHANNEL}}))
if __name__ == "__main__":
# note: reconnection handling needed.
ws = websocket.WebSocketApp("wss://ws.lightstream.bitflyer.com/json-rpc",
on_message=on_message, on_open=on_open)
ws.run_forever()
小数点以下の丸めに注意です。
intだと切り捨て、roundだと四捨五入、math.ceilだと切り上げです。実際の板を見ながら検討したのですが、パターンBとmath.ceilの組み合わせが一番しっくりきました。
つまり、BTC現物最終約定価格 x 1.05 - 1 です。
SFDbotの売値はどこ?
1円バーガーゆえに、上記の買値の1円上、つまり
BTC現物最終約定価格 x 1.05 が売値です。
これを高頻度に回すことによって利益を得ているようです。
ltpの変化に応じてcancel_orderとcreate_orderで注文を移動
BTC現物の最終約定価格は刻々と変化します。最終約定価格に合わせて買値と売値を移動させる必要があります。
そこで、fetch_open_ordersで現在の注文状況を調べ、注文があり価格が変化した場合cancel_orderで注文を削除、さらにcreate_orderで新たにorderを立てる必要があります。
ポイントは値段が変化しない限り注文を動かさないことです。cancelとcreateを繰り返すことは、行列の最後尾に並びなおすことと同じです。
SFDbotの問題点
このエントリーなどの価格が分かったところで、結局椅子取りゲームです。
いかに他より早くSFDが徴収されない5%以下の値で、買いを約定させることが出来るかが勝負になります。現状150BTCくらいの注文がSFDbotとして並んでいますが、そのすべてが約定してはいません。SFDbotの性能の差や、回線速度の差などが影響しているのかもしれません。
もしSFDbotを狩るなら、この出遅れ悪性能botを手始めにつぶす方法を考えるべきでしょうね。
最終約定価格が動いた時に遅れたbotを狩る
最終約定価格が下がった時に、cancel_orderが遅いbotに売りをぶつければ、板が厚い分確実に売ることができそうです。あとは買いのタイミングをどうするか、検討中です。
また追記、もしくは別noteにて書く予定です。
今日はここまで。読んでいただいてありがとうございます。
この記事が気に入ったらサポートをしてみませんか?