Stream real-time order fills, position updates, and wallet events from Bybit into your BunnyLogs stream via a small Python relay — no public server required.
Hosted bot (recommended) — go to Settings, click Connect Bybit, and paste your API key and secret. BunnyLogs opens and maintains the WebSocket connection on your behalf. Nothing to run locally.
Self-hosted relay — run the Python script below on any machine that already has your trading bot. Credentials stay on your own infrastructure. Follow the steps below.
Bybit exposes real-time account data through a private WebSocket channel. The relay script connects to that channel using your API key, listens for events, and forwards each one to BunnyLogs as a log entry. The script runs anywhere Python runs — your laptop, a VPS, or alongside your trading bot.
Log in to bybit.com, open the user menu in the top-right corner, and go to API Management.
Click Create New Key and choose System-generated API Keys. Give it a name (e.g. bunnylogs-relay) and set the following permissions — everything else can stay off:
| Category | Permission | Set to |
|---|---|---|
| Order | Read | ✓ On |
| Position | Read | ✓ On |
| Account | Read | ✓ On |
| Trade | all | ✗ Off |
| Withdrawal | all | ✗ Off |
Complete the 2FA verification. Bybit shows your API Key and Secret Key — copy both immediately. The secret is shown only once.
pip install pybit requests
Save the script below and run it. Set the four variables at the top:
import json
import requests
from pybit.unified_trading import WebSocket
BYBIT_API_KEY = "<your-api-key>"
BYBIT_API_SECRET = "<your-api-secret>"
BUNNYLOGS_UUID = "<your-uuid>"
PROGRAM = "bybit"
BUNNYLOGS_URL = f"https://bunnylogs.com/live/{BUNNYLOGS_UUID}"
def ship(message, level="INFO"):
try:
requests.post(
BUNNYLOGS_URL,
data={"message": message, "level": level, "program": PROGRAM},
timeout=5,
)
except Exception:
pass # never let a failed POST crash the relay
def handle_order(msg):
for order in msg.get("data", []):
symbol = order.get("symbol", "?")
side = order.get("side", "?")
qty = order.get("qty", "?")
price = order.get("avgPrice") or order.get("price", "?")
status = order.get("orderStatus", "?")
level = "ERROR" if status in ("Cancelled", "Rejected") else "INFO"
ship(f"Order {status}: {side} {qty} {symbol} @ {price}", level)
def handle_position(msg):
for pos in msg.get("data", []):
symbol = pos.get("symbol", "?")
side = pos.get("side", "?")
size = pos.get("size", "?")
pnl = pos.get("unrealisedPnl", "?")
ship(f"Position update: {side} {size} {symbol} unrealised PnL={pnl}")
def handle_wallet(msg):
for coin in msg.get("data", [{}]):
for balance in coin.get("coin", []):
name = balance.get("coin", "?")
total = balance.get("walletBalance", "?")
ship(f"Wallet update: {name} balance={total}")
ws = WebSocket(
testnet=False,
api_key=BYBIT_API_KEY,
api_secret=BYBIT_API_SECRET,
channel_type="private",
)
ws.order_stream(callback=handle_order)
ws.position_stream(callback=handle_position)
ws.wallet_stream(callback=handle_wallet)
print(f"Relay running — streaming Bybit events to BunnyLogs ({BUNNYLOGS_UUID})")
print("Press Ctrl+C to stop.")
import time
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("Stopped.")
Once the relay is running and you place or fill an order, entries appear in your stream immediately:
INFO bybit Order Filled: Buy 0.01 BTCUSDT @ 67420.5
INFO bybit Position update: Buy 0.01 BTCUSDT unrealised PnL=1.23
INFO bybit Wallet update: USDT balance=1243.87
ERROR bybit Order Rejected: Sell 0.05 ETHUSDT @ 3210.0
| Stream method | Fires when |
|---|---|
ws.order_stream() | An order is created, filled, partially filled, cancelled, or rejected |
ws.position_stream() | A position opens, changes size, or closes |
ws.wallet_stream() | Account balance changes (deposit, withdrawal, trade settlement) |
ws.execution_stream() | Individual trade executions (every fill tick) |
To keep the relay running continuously on a Linux server, create a systemd unit:
# /etc/systemd/system/bybit-relay.service
[Unit]
Description=Bybit → BunnyLogs relay
After=network.target
[Service]
ExecStart=/usr/bin/python3 /opt/bybit-relay/relay.py
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
systemctl enable --now bybit-relay
pybit handles WebSocket reconnection automatically; the relay recovers from dropped connections without restarting.ship() function swallows HTTP errors so a temporary BunnyLogs outage never crashes the relay.testnet=True in the WebSocket constructor to test against Bybit Testnet before going live.level=ERROR and program=bybit to get notified on rejected or cancelled orders via Slack, Telegram, or Discord.