趣旨
僕もせっかくbotが書けるようになったので鞘を取るようなbotを書いてみたいと思って一番簡単に書けそうなコードを書いてみました。
Bybitのステーブルコインの仕様を利用してあまりお金にならないけど、お金が減る可能性も極限に低いゆるい脱力botです。
USDC/USDTペアはBybitでは手数料がかかりません。
なので指値注文で1超・未満になった時、必ず後でその逆に行く性質を利用します。
以下のコードを実行する場合は全て自己責任でお願い致します。
本記事は教育目的での共有であり、投資を勧誘するものではありません。
環境設定
まずは仮想環境を用意します。
用意しなくてもコードは実行できますが、念のためにやっておいた方が良いです。
python3 -m venv myenv
source myenv/bin/activate
次にディレクトリを作ってそのディレクトリの中に移動します。
mkdir bybit
cd bybit
コード(コピペ可)
結果を先に表示すると以下のように注文が入ります。
このコードでは "Insufficient balance" が多発します。
それで正常な動きとなります。
Last Price: 1.0001
Selling USDC for USDT
An error occurred: bybit {"retCode":12131,"retMsg":"Insufficient balance.","result":{},"retExtInfo":{},"time":1706641077175}
Current time: 2024-01-30 18:57:54 UTC
-------
Last Price: 1.0001
Selling USDC for USDT
An error occurred: bybit {"retCode":12131,"retMsg":"Insufficient balance.","result":{},"retExtInfo":{},"time":1706641087431}
Current time: 2024-01-30 18:57:57 UTC
-------
Websocketの設定
Websocketはpybitの方が簡単そうだったので、そっちを使いました。
ここで価格情報を取得します。
価格の判定はここでは行わずにorder.py
に丸投げしてます。
import json
import threading
from order import place_order
from pybit.unified_trading import WebSocket
from time import sleep
from datetime import datetime
def convert_timestamp_to_readable(timestamp_ms):
timestamp_s = timestamp_ms / 1000
date_time = datetime.utcfromtimestamp(timestamp_s)
return date_time.strftime('%Y-%m-%d %H:%M:%S UTC')
ws = WebSocket(
testnet=False,
channel_type="spot",
)
def handle_message(message):
if isinstance(message, str):
message = json.loads(message)
if 'data' in message and 'lastPrice' in message['data']:
last_price = message['data']['lastPrice']
print(f"Last Price: {last_price}")
place_order(last_price)
if 'data' in message:
time = message['ts']
print(f"Current time: {convert_timestamp_to_readable(time)}")
print('-------')
sleep(3600)
ws.ticker_stream(
symbol="USDCUSDT",
callback=handle_message
)
while True:
sleep(10)
CCXT設定
今まで何度も使ってきたccxtのコードですね。
今回は注文の部分だけccxtにしました。
あとは数値を自由に弄って微調整すればbotが完成します。
import ccxt
import config
bybit = ccxt.bybit({
'apiKey': config.api_key,
'secret': config.api_secret,
})
def place_order(price_str):
try:
price = float(price_str)
if price > 1:
print("Selling USDC for USDT")
order = bybit.create_order('USDC/USDT', 'limit', 'sell', 10, 1.0001)
print(order)
elif price < 1:
print("Buying USDT with USDC")
order = bybit.create_order('USDC/USDT','limit', 'buy', 10, 0.9999)
print(order)
except ValueError:
print(f"Invalid price format: {price_str}")
pass
except Exception as e:
print(f"An error occurred: {e}")
pass
Config設定
APIキーを直に書いて保存しているのでセキュリティに問題があるかも知れません。気になる方は暗号化の方法を学んでご自身で暗号化してください。
api_key = ''
api_secret = ''