Source code for ccxt_pandas.wrappers.schemas.market_schema

"""Market, ticker, and funding rate data schema."""

import pandas as pd
import pandera.pandas as pa
from pandera.typing import Series

from ccxt_pandas.wrappers.schemas.base_schemas import BaseExchangeSchema


[docs] class MarketSchema(BaseExchangeSchema): """Market/ticker/funding rate data schema. Used by methods like load_markets, fetch_tickers, fetch_funding_rates, fetch_market_leverage_tiers, etc. Based on analysis of 20 exchanges, only 13 fields are ALWAYS present. All other fields are Optional even if very common. """ # Core identifiers id: Series[str] = pa.Field( unique=True, title="Market ID", description="Exchange-specific market ID" ) symbol: Series[str] = pa.Field( unique=True, title="Symbol", description="Unified CCXT market symbol" ) base: Series[str] = pa.Field(title="Base Currency", description="Base currency") quote: Series[str] = pa.Field(title="Quote Currency", description="Quote currency") baseId: Series[str] = pa.Field( title="Base ID", description="Exchange-specific base currency ID" ) quoteId: Series[str] = pa.Field( title="Quote ID", description="Exchange-specific quote currency ID" ) # Market type type: Series[str] = pa.Field( isin=["spot", "swap", "future", "option"], title="Market Type", description="Market type", ) # Market type booleans (always present) spot: Series[bool] = pa.Field(title="Spot", description="Is spot market") swap: Series[bool] = pa.Field(title="Swap", description="Is perpetual swap") future: Series[bool] = pa.Field(title="Future", description="Is futures contract") option: Series[bool] = pa.Field(title="Option", description="Is options contract") contract: Series[bool] = pa.Field(title="Contract", description="Is a contract market") # ======================================================================== # OPTIONAL FIELDS # ======================================================================== # Additional identifiers lowercaseId: Series[str] | None = pa.Field( nullable=True, title="Lowercase ID", description="Lowercase version of exchange ID", ) settle: Series[str] | None = pa.Field( nullable=True, title="Settlement Currency", description="Settlement currency (for futures/swaps)", ) settleId: Series[str] | None = pa.Field( nullable=True, title="Settlement ID", description="Exchange-specific settlement currency ID", ) # Market status (missing in bit2c) active: Series[bool] | None = pa.Field( nullable=True, title="Active", description="Whether market is active for trading", ) # Margin (missing in some, AND can be object type in ascendex, not bool!) margin: Series[bool] | None = pa.Field( nullable=True, title="Margin", description="Supports margin trading" ) # Contract details (14/19 each) linear: Series[bool] | None = pa.Field( nullable=True, title="Linear", description="Linear contract (settled in quote)" ) inverse: Series[bool] | None = pa.Field( nullable=True, title="Inverse", description="Inverse contract (settled in base)" ) subType: Series[str] | None = pa.Field( nullable=True, title="Subtype", description="Market subtype" ) contractSize: Series[float] | None = pa.Field( ge=0, nullable=True, title="Contract Size", description="Size of one contract" ) # Expiry and options (only in 5/19 exchanges) expiry: Series[pd.Timestamp] | None = pa.Field( nullable=True, title="Expiry", description="Expiry timestamp (as datetime)" ) expiryDatetime: Series[pd.Timestamp] | None = pa.Field( nullable=True, title="Expiry Datetime", description="Expiry datetime (alias)" ) strike: Series[float] | None = pa.Field( ge=0, nullable=True, title="Strike Price", description="Strike price (options)" ) optionType: Series[str] | None = pa.Field( nullable=True, isin=["call", "put"], title="Option Type", description="Option type", ) # Creation timestamp (7/19) created: Series[pd.Timestamp] | None = pa.Field( nullable=True, title="Created", description="Market creation timestamp" ) # Fee structure (15-16/19) taker: Series[float] | None = pa.Field( ge=0, nullable=True, title="Taker Fee", description="Taker fee rate" ) maker: Series[float] | None = pa.Field( ge=0, nullable=True, title="Maker Fee", description="Maker fee rate" ) tierBased: Series[bool] | None = pa.Field( nullable=True, title="Tier Based", description="Whether fees are tier-based" ) percentage: Series[bool] | None = pa.Field( nullable=True, title="Percentage", description="Whether fees are percentage-based", ) feeSide: Series[str] | None = pa.Field( nullable=True, isin=["get", "give", "base", "quote", "other"], title="Fee Side", description="Which side pays the fee", ) # Precision (17/19 for amount/price, but can be int64 in some exchanges!) precision_amount: Series[float] | None = pa.Field( nullable=True, title="Amount Precision", description="Amount precision (decimal places or tick size)", ) precision_price: Series[float] | None = pa.Field( nullable=True, title="Price Precision", description="Price precision (decimal places or tick size)", ) precision_base: Series[float] | None = pa.Field( nullable=True, title="Base Precision", description="Base currency precision" ) precision_quote: Series[float] | None = pa.Field( nullable=True, title="Quote Precision", description="Quote currency precision" ) # Limits - Amount (16/19 for min, 13/19 for max) limits_amount_min: Series[float] | None = pa.Field( ge=0, nullable=True, title="Min Amount", description="Minimum order amount" ) limits_amount_max: Series[float] | None = pa.Field( ge=0, nullable=True, title="Max Amount", description="Maximum order amount" ) # Limits - Price (14/19 for min, 10/19 for max) limits_price_min: Series[float] | None = pa.Field( ge=0, nullable=True, title="Min Price", description="Minimum order price" ) limits_price_max: Series[float] | None = pa.Field( ge=0, nullable=True, title="Max Price", description="Maximum order price" ) # Limits - Cost (12/19 for min, 5/19 for max) limits_cost_min: Series[float] | None = pa.Field( ge=0, nullable=True, title="Min Cost", description="Minimum order cost" ) limits_cost_max: Series[float] | None = pa.Field( ge=0, nullable=True, title="Max Cost", description="Maximum order cost" ) # Limits - Market (only 5/19 - Binance variants and Aster) limits_market_min: Series[float] | None = pa.Field( ge=0, nullable=True, title="Min Market Size", description="Minimum market order size", ) limits_market_max: Series[float] | None = pa.Field( ge=0, nullable=True, title="Max Market Size", description="Maximum market order size", ) # Limits - Leverage (only 3/19) limits_leverage_min: Series[float] | None = pa.Field( ge=0, nullable=True, title="Min Leverage", description="Minimum leverage" ) limits_leverage_max: Series[float] | None = pa.Field( ge=0, nullable=True, title="Max Leverage", description="Maximum leverage" ) # Margin modes (only 5/19 - Binance variants and Bitget) marginModes_cross: Series[bool] | None = pa.Field( nullable=True, title="Cross Margin", description="Supports cross margin" ) marginModes_isolated: Series[bool] | None = pa.Field( nullable=True, title="Isolated Margin", description="Supports isolated margin" ) # Additional rare fields index: Series[str] | None = pa.Field( nullable=True, title="Index", description="Index identifier" )
# Additional exchange-specific fields allowed via strict=False # Examples: id2, uuid, uppercaseId, feeCurrency, tiers_maker, tiers_taker, etc.