spb/crypto-trade-bot
Public
Python 54.7%
TypeScript 42.5%
SQL 1.9%
1"""Order book checksum for WebSocket v2 (docs.kraken.com/exchange/guides/websockets/book-checksum-v2).23Top 10 asks (low→high) then top 10 bids (high→low); each level encoded as4strip_leading_zeros(price without '.') + strip_leading_zeros(qty without '.'); CRC32 as unsigned int.5Prices/quantities must be kept as *strings or Decimal* with the exchange's precision.6"""78from __future__ import annotations910import zlib11from decimal import Decimal121314def _enc(x: Decimal | str) -> str:15 s = str(x)16 if "E" in s or "e" in s: # Decimal may render exponent notation for tiny numbers17 s = format(Decimal(s), "f")18 return s.replace(".", "").lstrip("0") or "0"192021def book_checksum(asks: list[tuple[Decimal | str, Decimal | str]], bids: list[tuple[Decimal | str, Decimal | str]]) -> int:22 """asks/bids are (price, qty) with exchange precision already applied (price_decimals / qty_decimals)."""23 a = sorted(asks, key=lambda lv: Decimal(str(lv[0])))[:10]24 b = sorted(bids, key=lambda lv: Decimal(str(lv[0])), reverse=True)[:10]25 s = "".join(_enc(p) + _enc(q) for p, q in a) + "".join(_enc(p) + _enc(q) for p, q in b)26 return zlib.crc32(s.encode()) & 0xFFFFFFFF272829def fmt_fixed(x: Decimal, decimals: int) -> str:30 """Format with exactly `decimals` decimals (what Kraken uses in the checksum string)."""31 q = Decimal(1).scaleb(-decimals)32 return format(x.quantize(q), "f")33