Cryptocurrency Exchange Websocket Data Feed Handler for normalized market data across 30+ exchanges
—
Standard constants for exchanges, channels, trading sides, and other enumerations, plus configuration management for feeds and authentication across all supported exchanges.
Constants for different types of market data feeds available across exchanges.
# Order Book Channels
L1_BOOK: str # Top of book (best bid/ask)
L2_BOOK: str # Price aggregated order book
L3_BOOK: str # Full order book with individual orders
# Market Data Channels
TRADES: str # Trade/transaction data
TICKER: str # Ticker/quote data
FUNDING: str # Funding rate data (perpetual contracts)
OPEN_INTEREST: str # Open interest data (derivatives)
LIQUIDATIONS: str # Liquidation events
INDEX: str # Index price data
CANDLES: str # Candlestick/OHLCV data
UNSUPPORTED: str # Placeholder for unsupported channelsConstants for authenticated account and trading data channels.
# Account Information
ORDER_INFO: str # Order status updates
FILLS: str # User trade fills/executions
TRANSACTIONS: str # Account deposits/withdrawals
BALANCES: str # Account balance updates
POSITIONS: str # Position updates (derivatives)
# Trading Operations
PLACE_ORDER: str # Order placement
CANCEL_ORDER: str # Order cancellation
ORDERS: str # Order list/history
ORDER_STATUS: str # Order status queries
TRADE_HISTORY: str # User trade historyString constants for all supported cryptocurrency exchanges.
# Major Spot Exchanges
COINBASE: str
BINANCE: str
KRAKEN: str
BITFINEX: str
BITSTAMP: str
GEMINI: str
KUCOIN: str
HITBTC: str
POLONIEX: str
# Futures and Derivatives
BINANCE_FUTURES: str
BINANCE_DELIVERY: str
KRAKEN_FUTURES: str
DERIBIT: str
BITMEX: str
BYBIT: str
OKX: str
PHEMEX: str
DELTA: str
# Regional Exchanges
BINANCE_US: str
BINANCE_TR: str
BITHUMB: str
UPBIT: str
INDEPENDENT_RESERVE: str
# Additional Exchanges
ASCENDEX: str
ASCENDEX_FUTURES: str
BEQUANT: str
BITDOTCOM: str
BITFLYER: str
BITGET: str
BLOCKCHAIN: str
CRYPTODOTCOM: str
DYDX: str
EXX: str
FMFW: str
GATEIO: str
GATEIO_FUTURES: str
HUOBI: str
HUOBI_DM: str
HUOBI_SWAP: str
OKCOIN: str
PROBIT: strConstants for trading sides, order types, and other trading-related enumerations.
# Trading Sides
BUY: str # Buy side
SELL: str # Sell side
BID: str # Bid side (order book)
ASK: str # Ask side (order book)
UND: str # Undefined side
# Liquidity Types
MAKER: str # Maker liquidity
TAKER: str # Taker liquidity
# Position Types
LONG: str # Long position
SHORT: str # Short position
BOTH: str # Both long and short (hedge mode)
# Order Types
LIMIT: str # Limit order
MARKET: str # Market order
STOP_LIMIT: str # Stop limit order
STOP_MARKET: str # Stop market order
MAKER_OR_CANCEL: str # Maker-or-cancel order
FILL_OR_KILL: str # Fill-or-kill order
IMMEDIATE_OR_CANCEL: str # Immediate-or-cancel order
GOOD_TIL_CANCELED: str # Good-till-canceled order
TRIGGER_LIMIT: str # Trigger limit order
TRIGGER_MARKET: str # Trigger market order
MARGIN_LIMIT: str # Margin limit order
MARGIN_MARKET: str # Margin market orderConstants for order status states across all exchanges.
# Order Status
OPEN: str # Order is open/active
PENDING: str # Order is pending
FILLED: str # Order is completely filled
PARTIAL: str # Order is partially filled
CANCELLED: str # Order is cancelled
UNFILLED: str # Order is unfilled
EXPIRED: str # Order has expired
SUSPENDED: str # Order is suspended
FAILED: str # Order failed
SUBMITTING: str # Order is being submitted
CANCELLING: str # Order is being cancelled
CLOSED: str # Order is closedConstants for different types of financial instruments.
# Instrument Types
CURRENCY: str # Currency/spot pairs
FUTURES: str # Futures contracts
PERPETUAL: str # Perpetual contracts
OPTION: str # Options contracts
OPTION_COMBO: str # Option combinations
FUTURE_COMBO: str # Future combinations
SPOT: str # Spot trading
CALL: str # Call options
PUT: str # Put options
FX: str # Foreign exchangeClasses for managing feed configuration and settings.
class Config:
"""Configuration management for feeds and exchanges."""
def __init__(self, config=None):
"""
Initialize configuration with file, dict, or defaults.
Args:
config (str, dict, optional):
- str: Path to YAML config file
- dict: Configuration dictionary
- None: Use default configuration
"""
@property
def log_msg(self) -> str:
"""Configuration loading log message."""
class AttrDict(dict):
"""Dictionary with attribute-style access for nested configurations."""
def __init__(self, d=None):
"""
Initialize with optional dictionary.
Args:
d (dict, optional): Initial dictionary data
"""
def __getattr__(self, key):
"""Get attribute using dot notation."""
def __setattr__(self, key, value):
"""Set attribute using dot notation."""
def __missing__(self, key):
"""Return empty AttrDict for missing keys."""Classes and functions for managing symbol normalization across exchanges.
class Symbol:
"""Represents trading symbols with normalization."""
def __init__(self, base, quote, type=SPOT, strike_price=None, option_type=None, expiry_date=None, expiry_normalize=True):
"""
Initialize symbol.
Args:
base (str): Base currency/asset
quote (str): Quote currency/asset
type (str): Instrument type (SPOT, FUTURES, etc.)
strike_price (float, optional): Strike price for options
option_type (str, optional): CALL or PUT for options
expiry_date (str, optional): Expiry date for derivatives
expiry_normalize (bool): Whether to normalize expiry format
"""
@property
def normalized(self) -> str:
"""Get normalized symbol string."""
@staticmethod
def month_code(month: int) -> str:
"""Get futures month code for month number."""
@staticmethod
def date_format(date: str) -> str:
"""Format date string for symbols."""
class Symbols:
"""Global symbol registry for exchange symbol mappings."""
def clear(self): ...
def load_all(self): ...
def set(self, exchange, normalized, exchange_info): ...
def get(self, exchange): ...
def populated(self, exchange): ...
def find(self, symbol): ...
def str_to_symbol(symbol: str) -> Symbol:
"""Convert string to Symbol object."""from cryptofeed import FeedHandler
from cryptofeed.exchanges import Coinbase
from cryptofeed.defines import TRADES, TICKER, L2_BOOK, FUNDING
def trade_handler(trade):
print(f'Trade: {trade}')
def ticker_handler(ticker):
print(f'Ticker: {ticker}')
fh = FeedHandler()
fh.add_feed(Coinbase(
symbols=['BTC-USD'],
channels=[TRADES, TICKER, L2_BOOK], # Use constants instead of strings
callbacks={
TRADES: trade_handler,
TICKER: ticker_handler
}
))
fh.run()from cryptofeed.defines import COINBASE, BINANCE, KRAKEN
from cryptofeed.exchanges import EXCHANGE_MAP
# Get exchange class from constant
exchange_class = EXCHANGE_MAP[COINBASE]
exchange = exchange_class()
# Check supported exchanges
supported_exchanges = list(EXCHANGE_MAP.keys())
print(f'Supported exchanges: {supported_exchanges}')from cryptofeed import FeedHandler
from cryptofeed.config import Config
# YAML configuration file example (config.yaml):
"""
log:
filename: feed.log
level: INFO
feeds:
coinbase:
exchange: coinbase
symbols: [BTC-USD, ETH-USD]
channels: [trades, ticker]
binance:
exchange: binance
symbols: [BTCUSDT, ETHUSDT]
channels: [trades, book]
"""
# Load configuration
config = Config('config.yaml')
fh = FeedHandler(config=config)
fh.run()from cryptofeed.defines import BUY, SELL, LIMIT, MARKET, MAKER, TAKER
def order_handler(order):
"""Process order updates using constants."""
if order.side == BUY:
print(f'Buy order: {order.amount} @ {order.price}')
elif order.side == SELL:
print(f'Sell order: {order.amount} @ {order.price}')
if order.type == LIMIT:
print('Limit order')
elif order.type == MARKET:
print('Market order')
def fill_handler(fill):
"""Process fills using liquidity constants."""
if fill.liquidity == MAKER:
print('Maker fill (provided liquidity)')
elif fill.liquidity == TAKER:
print('Taker fill (took liquidity)')from cryptofeed.symbols import Symbol, str_to_symbol
from cryptofeed.defines import SPOT, FUTURES, CALL
# Create spot symbol
btc_usd = Symbol('BTC', 'USD', SPOT)
print(btc_usd.normalized) # BTC-USD
# Create futures symbol
btc_fut = Symbol('BTC', 'USD', FUTURES, expiry_date='2024-03-29')
print(btc_fut.normalized) # BTC-USD-29MAR24
# Create option symbol
btc_call = Symbol('BTC', 'USD', CALL, strike_price=50000, expiry_date='2024-03-29')
print(btc_call.normalized) # BTC-USD-29MAR24-50000-C
# Parse symbol string
symbol = str_to_symbol('BTC-USD')
print(f'Base: {symbol.base}, Quote: {symbol.quote}')import os
from cryptofeed import FeedHandler
from cryptofeed.exchanges import Coinbase
# Use environment variables for API credentials
config = {
'coinbase': {
'key_id': os.getenv('COINBASE_API_KEY'),
'secret': os.getenv('COINBASE_SECRET'),
'passphrase': os.getenv('COINBASE_PASSPHRASE')
}
}
fh = FeedHandler()
fh.add_feed(Coinbase(
symbols=['BTC-USD'],
channels=[TRADES],
config=config
))
fh.run()from cryptofeed.exchanges import Coinbase, Binance
from cryptofeed.defines import *
# Check what channels each exchange supports
coinbase = Coinbase()
info = coinbase.info()
print(f"Coinbase channels: {info.get('channels', [])}")
print(f"Requires authentication: {info.get('authenticated_channels', [])}")
# Check symbol support
symbols = coinbase.symbols()
print(f"Coinbase supports {len(symbols)} symbols")
# Get channel mapping
channel_map = coinbase.std_channel_to_exchange(TRADES)
print(f"TRADES maps to: {channel_map}")Built-in exception classes for error handling and validation across the library.
class MissingSequenceNumber(Exception):
"""Missing sequence number in data."""
class MissingMessage(Exception):
"""Missing expected message."""
class UnsupportedSymbol(Exception):
"""Symbol not supported by exchange."""
class UnsupportedDataFeed(Exception):
"""Data feed not supported."""
class UnsupportedTradingOption(Exception):
"""Trading option not supported."""
class UnsupportedType(Exception):
"""Type not supported."""
class ExhaustedRetries(Exception):
"""Retries exhausted."""
class BidAskOverlapping(Exception):
"""Bid/ask price overlap detected."""
class BadChecksum(Exception):
"""Checksum validation failed."""
class RestResponseError(Exception):
"""REST API response error."""
class ConnectionClosed(Exception):
"""Connection closed unexpectedly."""
class UnexpectedMessage(Exception):
"""Unexpected message received."""from cryptofeed.defines import OPEN, FILLED, CANCELLED, PARTIAL
def order_status_handler(order_info):
"""Handle different order statuses."""
if order_info.status == OPEN:
print(f'Order {order_info.id} is open')
elif order_info.status == FILLED:
print(f'Order {order_info.id} is completely filled')
elif order_info.status == PARTIAL:
filled_amount = order_info.amount - order_info.remaining
print(f'Order {order_info.id} is partially filled: {filled_amount}/{order_info.amount}')
elif order_info.status == CANCELLED:
print(f'Order {order_info.id} was cancelled')Install with Tessl CLI
npx tessl i tessl/pypi-cryptofeed