Rewrite all websocket examples according to v3.0.0b3's changes.

This commit is contained in:
Davide Casale
2023-10-26 17:59:44 +02:00
parent 1ec6c49428
commit 1accf92c57
7 changed files with 111 additions and 84 deletions

View File

@@ -2,39 +2,39 @@
import os import os
from bfxapi import Client, WSS_HOST from bfxapi import Client
from bfxapi.enums import Error, OrderType
from bfxapi.types import Notification, Order from bfxapi.types import Notification, Order
bfx = Client( bfx = Client(
wss_host=WSS_HOST,
api_key=os.getenv("BFX_API_KEY"), api_key=os.getenv("BFX_API_KEY"),
api_secret=os.getenv("BFX_API_SECRET") api_secret=os.getenv("BFX_API_SECRET"),
) )
@bfx.wss.on("authenticated") @bfx.wss.on("authenticated")
async def on_authenticated(event): async def on_authenticated(event):
print(f"Authentication: {event}") print(f"Authentication: {event}")
await bfx.wss.inputs.submit_order( await bfx.wss.inputs.submit_order(
type=OrderType.EXCHANGE_LIMIT, type="EXCHANGE LIMIT", symbol="tBTCUSD", amount=0.165212, price=30264.0
symbol="tBTCUSD",
amount="0.1",
price="10000.0"
) )
print("The order has been sent.") print("The order has been sent.")
@bfx.wss.on("on-req-notification") @bfx.wss.on("on-req-notification")
async def on_notification(notification: Notification[Order]): async def on_notification(notification: Notification[Order]):
print(f"Notification: {notification}.") print(f"Notification: {notification}.")
@bfx.wss.on("order_new") @bfx.wss.on("order_new")
async def on_order_new(order_new: Order): async def on_order_new(order_new: Order):
print(f"Order new: {order_new}") print(f"Order new: {order_new}")
@bfx.wss.on("subscribed") @bfx.wss.on("subscribed")
def on_subscribed(subscription): def on_subscribed(subscription):
print(f"Subscription successful for <{subscription}>.") print(f"Subscription successful for <{subscription}>.")
bfx.wss.run() bfx.wss.run()

View File

@@ -1,19 +1,18 @@
# python -c "import examples.websocket.auth.wallets" # python -c "import examples.websocket.auth.wallets"
import os import os
from typing import List from typing import List
from bfxapi import Client from bfxapi import Client
from bfxapi.enums import Error
from bfxapi.types import Wallet from bfxapi.types import Wallet
bfx = Client( bfx = Client(
api_key=os.getenv("BFX_API_KEY"), api_key=os.getenv("BFX_API_KEY"),
api_secret=os.getenv("BFX_API_SECRET"), api_secret=os.getenv("BFX_API_SECRET"),
filters=["wallet"] filters=["wallet"],
) )
@bfx.wss.on("wallet_snapshot") @bfx.wss.on("wallet_snapshot")
def on_wallet_snapshot(wallets: List[Wallet]): def on_wallet_snapshot(wallets: List[Wallet]):
for wallet in wallets: for wallet in wallets:
@@ -21,8 +20,10 @@ def on_wallet_snapshot(wallets: List[Wallet]):
print(f"Available balance: {wallet.available_balance}") print(f"Available balance: {wallet.available_balance}")
print(f"Wallet trade details: {wallet.trade_details}") print(f"Wallet trade details: {wallet.trade_details}")
@bfx.wss.on("wallet_update") @bfx.wss.on("wallet_update")
def on_wallet_update(wallet: Wallet): def on_wallet_update(wallet: Wallet):
print(f"Wallet update: {wallet}") print(f"Wallet update: {wallet}")
bfx.wss.run() bfx.wss.run()

View File

@@ -1,19 +1,20 @@
# python -c "import examples.websocket.public.derivatives_status" # python -c "import examples.websocket.public.derivatives_status"
from bfxapi import Client, PUB_WSS_HOST from bfxapi import Client
from bfxapi.types import DerivativesStatus from bfxapi.types import DerivativesStatus
from bfxapi.websocket.subscriptions import Status from bfxapi.websocket.subscriptions import Status
from bfxapi.websocket.enums import Error, Channel bfx = Client()
bfx = Client(wss_host=PUB_WSS_HOST)
@bfx.wss.on("derivatives_status_update") @bfx.wss.on("derivatives_status_update")
def on_derivatives_status_update(subscription: Status, data: DerivativesStatus): def on_derivatives_status_update(subscription: Status, data: DerivativesStatus):
print(f"{subscription}:", data) print(f"{subscription}:", data)
@bfx.wss.on("open") @bfx.wss.on("open")
async def on_open(): async def on_open():
await bfx.wss.subscribe(Channel.STATUS, key="deriv:tBTCF0:USTF0") await bfx.wss.subscribe("status", key="deriv:tBTCF0:USTF0")
bfx.wss.run() bfx.wss.run()

View File

@@ -1,27 +1,21 @@
# python -c "import examples.websocket.public.order_book" # python -c "import examples.websocket.public.order_book"
from collections import OrderedDict
from typing import List, Dict
import zlib import zlib
from collections import OrderedDict
from typing import Dict, List
from bfxapi import Client, PUB_WSS_HOST from bfxapi import Client
from bfxapi.types import TradingPairBook from bfxapi.types import TradingPairBook
from bfxapi.websocket.subscriptions import Book from bfxapi.websocket.subscriptions import Book
from bfxapi.websocket.enums import Channel, Error
class OrderBook: class OrderBook:
def __init__(self, symbols: List[str]): def __init__(self, symbols: List[str]):
self.__order_book = { self.__order_book = {
symbol: { symbol: {"bids": OrderedDict(), "asks": OrderedDict()} for symbol in symbols
"bids": OrderedDict(), "asks": OrderedDict()
} for symbol in symbols
} }
self.cooldown: Dict[str, bool] = \ self.cooldown: Dict[str, bool] = {symbol: False for symbol in symbols}
{ symbol: False for symbol in symbols }
def update(self, symbol: str, data: TradingPairBook) -> None: def update(self, symbol: str, data: TradingPairBook) -> None:
price, count, amount = data.price, data.count, data.amount price, count, amount = data.price, data.count, data.amount
@@ -30,9 +24,9 @@ class OrderBook:
if count > 0: if count > 0:
self.__order_book[symbol][kind][price] = { self.__order_book[symbol][kind][price] = {
"price": price, "price": price,
"count": count, "count": count,
"amount": amount "amount": amount,
} }
if count == 0: if count == 0:
@@ -40,23 +34,31 @@ class OrderBook:
del self.__order_book[symbol][kind][price] del self.__order_book[symbol][kind][price]
def verify(self, symbol: str, checksum: int) -> bool: def verify(self, symbol: str, checksum: int) -> bool:
values: List[int] = [ ] values: List[int] = []
bids = sorted([ (data["price"], data["count"], data["amount"]) \ bids = sorted(
for _, data in self.__order_book[symbol]["bids"].items() ], [
key=lambda data: -data[0]) (data["price"], data["count"], data["amount"])
for _, data in self.__order_book[symbol]["bids"].items()
],
key=lambda data: -data[0],
)
asks = sorted([ (data["price"], data["count"], data["amount"]) \ asks = sorted(
for _, data in self.__order_book[symbol]["asks"].items() ], [
key=lambda data: data[0]) (data["price"], data["count"], data["amount"])
for _, data in self.__order_book[symbol]["asks"].items()
],
key=lambda data: data[0],
)
if len(bids) < 25 or len(asks) < 25: if len(bids) < 25 or len(asks) < 25:
raise AssertionError("Not enough bids or asks (need at least 25).") raise AssertionError("Not enough bids or asks (need at least 25).")
for _i in range(25): for _i in range(25):
bid, ask = bids[_i], asks[_i] bid, ask = bids[_i], asks[_i]
values.extend([ bid[0], bid[2] ]) values.extend([bid[0], bid[2]])
values.extend([ ask[0], ask[2] ]) values.extend([ask[0], ask[2]])
local = ":".join(str(value) for value in values) local = ":".join(str(value) for value in values)
@@ -64,30 +66,36 @@ class OrderBook:
return crc32 == checksum return crc32 == checksum
SYMBOLS = [ "tLTCBTC", "tETHUSD", "tETHBTC" ]
SYMBOLS = ["tLTCBTC", "tETHUSD", "tETHBTC"]
order_book = OrderBook(symbols=SYMBOLS) order_book = OrderBook(symbols=SYMBOLS)
bfx = Client(wss_host=PUB_WSS_HOST) bfx = Client()
@bfx.wss.on("open") @bfx.wss.on("open")
async def on_open(): async def on_open():
for symbol in SYMBOLS: for symbol in SYMBOLS:
await bfx.wss.subscribe(Channel.BOOK, symbol=symbol) await bfx.wss.subscribe("book", symbol=symbol)
@bfx.wss.on("subscribed") @bfx.wss.on("subscribed")
def on_subscribed(subscription): def on_subscribed(subscription):
print(f"Subscription successful for pair <{subscription['pair']}>") print(f"Subscription successful for symbol <{subscription['symbol']}>")
@bfx.wss.on("t_book_snapshot") @bfx.wss.on("t_book_snapshot")
def on_t_book_snapshot(subscription: Book, snapshot: List[TradingPairBook]): def on_t_book_snapshot(subscription: Book, snapshot: List[TradingPairBook]):
for data in snapshot: for data in snapshot:
order_book.update(subscription["symbol"], data) order_book.update(subscription["symbol"], data)
@bfx.wss.on("t_book_update") @bfx.wss.on("t_book_update")
def on_t_book_update(subscription: Book, data: TradingPairBook): def on_t_book_update(subscription: Book, data: TradingPairBook):
order_book.update(subscription["symbol"], data) order_book.update(subscription["symbol"], data)
@bfx.wss.on("checksum") @bfx.wss.on("checksum")
async def on_checksum(subscription: Book, value: int): async def on_checksum(subscription: Book, value: int):
symbol = subscription["symbol"] symbol = subscription["symbol"]
@@ -95,11 +103,14 @@ async def on_checksum(subscription: Book, value: int):
if order_book.verify(symbol, value): if order_book.verify(symbol, value):
order_book.cooldown[symbol] = False order_book.cooldown[symbol] = False
elif not order_book.cooldown[symbol]: elif not order_book.cooldown[symbol]:
print("Mismatch between local and remote checksums: " print(
f"restarting book for symbol <{symbol}>...") "Mismatch between local and remote checksums: "
f"restarting book for symbol <{symbol}>..."
)
await bfx.wss.resubscribe(sub_id=subscription["sub_id"]) await bfx.wss.resubscribe(sub_id=subscription["sub_id"])
order_book.cooldown[symbol] = True order_book.cooldown[symbol] = True
bfx.wss.run() bfx.wss.run()

View File

@@ -1,27 +1,21 @@
# python -c "import examples.websocket.public.raw_order_book" # python -c "import examples.websocket.public.raw_order_book"
from collections import OrderedDict
from typing import List, Dict
import zlib import zlib
from collections import OrderedDict
from typing import Dict, List
from bfxapi import Client, PUB_WSS_HOST from bfxapi import Client
from bfxapi.types import TradingPairRawBook from bfxapi.types import TradingPairRawBook
from bfxapi.websocket.subscriptions import Book from bfxapi.websocket.subscriptions import Book
from bfxapi.websocket.enums import Channel, Error
class RawOrderBook: class RawOrderBook:
def __init__(self, symbols: List[str]): def __init__(self, symbols: List[str]):
self.__raw_order_book = { self.__raw_order_book = {
symbol: { symbol: {"bids": OrderedDict(), "asks": OrderedDict()} for symbol in symbols
"bids": OrderedDict(), "asks": OrderedDict()
} for symbol in symbols
} }
self.cooldown: Dict[str, bool] = \ self.cooldown: Dict[str, bool] = {symbol: False for symbol in symbols}
{ symbol: False for symbol in symbols }
def update(self, symbol: str, data: TradingPairRawBook) -> None: def update(self, symbol: str, data: TradingPairRawBook) -> None:
order_id, price, amount = data.order_id, data.price, data.amount order_id, price, amount = data.order_id, data.price, data.amount
@@ -31,8 +25,8 @@ class RawOrderBook:
if price > 0: if price > 0:
self.__raw_order_book[symbol][kind][order_id] = { self.__raw_order_book[symbol][kind][order_id] = {
"order_id": order_id, "order_id": order_id,
"price": price, "price": price,
"amount": amount "amount": amount,
} }
if price == 0: if price == 0:
@@ -40,23 +34,31 @@ class RawOrderBook:
del self.__raw_order_book[symbol][kind][order_id] del self.__raw_order_book[symbol][kind][order_id]
def verify(self, symbol: str, checksum: int) -> bool: def verify(self, symbol: str, checksum: int) -> bool:
values: List[int] = [ ] values: List[int] = []
bids = sorted([ (data["order_id"], data["price"], data["amount"]) \ bids = sorted(
for _, data in self.__raw_order_book[symbol]["bids"].items() ], [
key=lambda data: (-data[1], data[0])) (data["order_id"], data["price"], data["amount"])
for _, data in self.__raw_order_book[symbol]["bids"].items()
],
key=lambda data: (-data[1], data[0]),
)
asks = sorted([ (data["order_id"], data["price"], data["amount"]) \ asks = sorted(
for _, data in self.__raw_order_book[symbol]["asks"].items() ], [
key=lambda data: (data[1], data[0])) (data["order_id"], data["price"], data["amount"])
for _, data in self.__raw_order_book[symbol]["asks"].items()
],
key=lambda data: (data[1], data[0]),
)
if len(bids) < 25 or len(asks) < 25: if len(bids) < 25 or len(asks) < 25:
raise AssertionError("Not enough bids or asks (need at least 25).") raise AssertionError("Not enough bids or asks (need at least 25).")
for _i in range(25): for _i in range(25):
bid, ask = bids[_i], asks[_i] bid, ask = bids[_i], asks[_i]
values.extend([ bid[0], bid[2] ]) values.extend([bid[0], bid[2]])
values.extend([ ask[0], ask[2] ]) values.extend([ask[0], ask[2]])
local = ":".join(str(value) for value in values) local = ":".join(str(value) for value in values)
@@ -64,30 +66,36 @@ class RawOrderBook:
return crc32 == checksum return crc32 == checksum
SYMBOLS = [ "tLTCBTC", "tETHUSD", "tETHBTC" ]
SYMBOLS = ["tLTCBTC", "tETHUSD", "tETHBTC"]
raw_order_book = RawOrderBook(symbols=SYMBOLS) raw_order_book = RawOrderBook(symbols=SYMBOLS)
bfx = Client(wss_host=PUB_WSS_HOST) bfx = Client()
@bfx.wss.on("open") @bfx.wss.on("open")
async def on_open(): async def on_open():
for symbol in SYMBOLS: for symbol in SYMBOLS:
await bfx.wss.subscribe(Channel.BOOK, symbol=symbol, prec="R0") await bfx.wss.subscribe("book", symbol=symbol, prec="R0")
@bfx.wss.on("subscribed") @bfx.wss.on("subscribed")
def on_subscribed(subscription): def on_subscribed(subscription):
print(f"Subscription successful for pair <{subscription['pair']}>") print(f"Subscription successful for symbol <{subscription['symbol']}>")
@bfx.wss.on("t_raw_book_snapshot") @bfx.wss.on("t_raw_book_snapshot")
def on_t_raw_book_snapshot(subscription: Book, snapshot: List[TradingPairRawBook]): def on_t_raw_book_snapshot(subscription: Book, snapshot: List[TradingPairRawBook]):
for data in snapshot: for data in snapshot:
raw_order_book.update(subscription["symbol"], data) raw_order_book.update(subscription["symbol"], data)
@bfx.wss.on("t_raw_book_update") @bfx.wss.on("t_raw_book_update")
def on_t_raw_book_update(subscription: Book, data: TradingPairRawBook): def on_t_raw_book_update(subscription: Book, data: TradingPairRawBook):
raw_order_book.update(subscription["symbol"], data) raw_order_book.update(subscription["symbol"], data)
@bfx.wss.on("checksum") @bfx.wss.on("checksum")
async def on_checksum(subscription: Book, value: int): async def on_checksum(subscription: Book, value: int):
symbol = subscription["symbol"] symbol = subscription["symbol"]
@@ -95,11 +103,14 @@ async def on_checksum(subscription: Book, value: int):
if raw_order_book.verify(symbol, value): if raw_order_book.verify(symbol, value):
raw_order_book.cooldown[symbol] = False raw_order_book.cooldown[symbol] = False
elif not raw_order_book.cooldown[symbol]: elif not raw_order_book.cooldown[symbol]:
print("Mismatch between local and remote checksums: " print(
f"restarting book for symbol <{symbol}>...") "Mismatch between local and remote checksums: "
f"restarting book for symbol <{symbol}>..."
)
await bfx.wss.resubscribe(sub_id=subscription["sub_id"]) await bfx.wss.resubscribe(sub_id=subscription["sub_id"])
raw_order_book.cooldown[symbol] = True raw_order_book.cooldown[symbol] = True
bfx.wss.run() bfx.wss.run()

View File

@@ -1,12 +1,11 @@
# python -c "import examples.websocket.public.ticker" # python -c "import examples.websocket.public.ticker"
from bfxapi import Client, PUB_WSS_HOST from bfxapi import Client
from bfxapi.types import TradingPairTicker from bfxapi.types import TradingPairTicker
from bfxapi.websocket.subscriptions import Ticker from bfxapi.websocket.subscriptions import Ticker
from bfxapi.websocket.enums import Channel
bfx = Client(wss_host=PUB_WSS_HOST) bfx = Client()
@bfx.wss.on("t_ticker_update") @bfx.wss.on("t_ticker_update")
def on_t_ticker_update(subscription: Ticker, data: TradingPairTicker): def on_t_ticker_update(subscription: Ticker, data: TradingPairTicker):
@@ -14,8 +13,10 @@ def on_t_ticker_update(subscription: Ticker, data: TradingPairTicker):
print(f"Data: {data}") print(f"Data: {data}")
@bfx.wss.on("open") @bfx.wss.on("open")
async def on_open(): async def on_open():
await bfx.wss.subscribe(Channel.TICKER, symbol="tBTCUSD") await bfx.wss.subscribe("ticker", symbol="tBTCUSD")
bfx.wss.run() bfx.wss.run()

View File

@@ -1,25 +1,27 @@
# python -c "import examples.websocket.public.trades" # python -c "import examples.websocket.public.trades"
from bfxapi import Client, PUB_WSS_HOST from bfxapi import Client
from bfxapi.types import Candle, TradingPairTrade from bfxapi.types import Candle, TradingPairTrade
from bfxapi.websocket.subscriptions import Candles, Trades from bfxapi.websocket.subscriptions import Candles, Trades
from bfxapi.websocket.enums import Error, Channel
bfx = Client(wss_host=PUB_WSS_HOST) bfx = Client()
@bfx.wss.on("candles_update") @bfx.wss.on("candles_update")
def on_candles_update(_sub: Candles, candle: Candle): def on_candles_update(_sub: Candles, candle: Candle):
print(f"New candle: {candle}") print(f"New candle: {candle}")
@bfx.wss.on("t_trade_execution") @bfx.wss.on("t_trade_execution")
def on_t_trade_execution(_sub: Trades, trade: TradingPairTrade): def on_t_trade_execution(_sub: Trades, trade: TradingPairTrade):
print(f"New trade: {trade}") print(f"New trade: {trade}")
@bfx.wss.on("open") @bfx.wss.on("open")
async def on_open(): async def on_open():
await bfx.wss.subscribe(Channel.CANDLES, key="trade:1m:tBTCUSD") await bfx.wss.subscribe("candles", key="trade:1m:tBTCUSD")
await bfx.wss.subscribe("trades", symbol="tBTCUSD")
await bfx.wss.subscribe(Channel.TRADES, symbol="tBTCUSD")
bfx.wss.run() bfx.wss.run()