Exchange configuration struct and constructor.
Holds everything needed to make API calls for a specific exchange instance: resolved base URLs, rate limits, credentials, capabilities, and lean spec data.
This is a pure data struct — no process. Rate limiting, HTTP execution, and
signing are handled by other modules that receive %Exchange{} as input.
Examples
# Public-only (no credentials)
{:ok, exchange} = CCXT.Exchange.new("bybit")
exchange.base_urls
#=> %{"public" => "https://api.bybit.com", ...}
# With credentials
{:ok, exchange} = CCXT.Exchange.new("bybit", api_key: "abc", secret: "xyz")
exchange.credentials
#=> %CCXT.Credentials{api_key: "abc", secret: "xyz", ...}
# Sandbox mode (uses testnet URLs)
{:ok, exchange} = CCXT.Exchange.new("bybit", sandbox: true)
Summary
Functions
Generates introspection functions and endpoint wrappers from a spec ID.
Macro entry point: use CCXT.Exchange, spec: "bybit" generates an exchange module.
Pre-computes a flat list of endpoint configs from the nested API tree.
Builds quoted endpoint wrapper functions from a list of endpoint configs.
Builds the quoted module body from prepared generate data.
Builds unified method mapping from spec data and pre-computed endpoint configs.
Classifies signing pattern and builds @external_resource AST for parent specs.
Checks if the exchange supports a given capability.
Creates an exchange configuration from an exchange ID and options.
Creates an exchange configuration, raising on error.
Prepares all compile-time data for the generator macro.
Returns the exchange's tier string, or nil if the spec omits it.
Types
@type error_body_check() :: %{ field: String.t() | nil, field2: String.t() | nil, roles: [error_body_role()], sentinel_values: [sentinel_value()] }
@type error_body_role() :: :error_code | :status_sentinel
@type sentinel_operator() :: String.t()
@type sentinel_value() :: %{operator: sentinel_operator(), value: String.t()}
@type t() :: %CCXT.Exchange{ base_urls: map(), broad_error_patterns: %{required(String.t()) => CCXT.Error.error_type()}, common_currencies: %{required(String.t()) => String.t()}, credentials: CCXT.Credentials.t() | nil, error_body_checks: [error_body_check()], error_code_fields: [String.t()], error_codes: %{required(String.t()) => CCXT.Error.error_type()}, has: %{required(String.t()) => boolean() | String.t()}, hostname: String.t() | nil, http_exceptions: %{required(String.t()) => CCXT.Error.error_type()}, id: String.t(), module: module() | nil, name: String.t(), options: map(), outbound_aliases: %{required(String.t()) => String.t()}, rate_limit_ms: number(), request_defaults: %{required(String.t()) => %{required(String.t()) => term()}}, required_credentials: %{required(String.t()) => boolean()}, sandbox: boolean(), signing_config: map(), signing_pattern: CCXT.Signing.pattern() | nil, spec: map(), symbol_patterns: %{required(atom()) => CCXT.Symbol.pattern_config()}, tier: String.t() | nil }
Functions
Generates introspection functions and endpoint wrappers from a spec ID.
Macro entry point: use CCXT.Exchange, spec: "bybit" generates an exchange module.
Pre-computes a flat list of endpoint configs from the nested API tree.
Called at compile time by __generate__/1. Recursively traverses the spec's
API tree until it finds HTTP method keys (get, post, etc.), then extracts
endpoint configs from the level below.
Handles three spec patterns:
- Standard:
%{visibility => %{method => %{path => weight}}} - Deep nesting:
%{api_type => %{version => %{visibility => %{method => ...}}}} - Array endpoints:
%{... => %{method => [list_of_paths]}}
All intermediate keys above the HTTP method become the :sections list.
Examples
CCXT.Exchange.build_endpoint_configs(%{
"public" => %{"get" => %{"v5/market/tickers" => 5}},
"private" => %{"post" => %{"v5/order/create" => 2.5}}
})
#=> [
#=> %{name: :public_get_v5_market_tickers, method: :get,
#=> path: "v5/market/tickers", sections: ["public"], weight: 5},
#=> %{name: :private_post_v5_order_create, method: :post,
#=> path: "v5/order/create", sections: ["private"], weight: 2.5}
#=> ]
Builds quoted endpoint wrapper functions from a list of endpoint configs.
Called at compile time by __generate__/1. Each generated function embeds
its endpoint config as a literal and delegates to CCXT.Dispatch.call/4.
Example
For a config %{name: :public_get_v5_market_tickers, ...}, generates:
def public_get_v5_market_tickers(exchange, params \\ %{}, opts \\ [])
def public_get_v5_market_tickers(%CCXT.Exchange{} = exchange, params, opts) do
CCXT.Dispatch.call(exchange, %{...}, params, opts)
end
Builds the quoted module body from prepared generate data.
Called by both __generate__/1 (macro path) and CCXT.Exchanges
(Module.create path) to ensure a single source of truth.
Options
:moduledoc— optional@moduledocstring to inject. The macro path leaves this to the caller;CCXT.Exchangesprovides one per exchange.
Builds unified method mapping from spec data and pre-computed endpoint configs.
Classifies signing pattern and builds @external_resource AST for parent specs.
Checks if the exchange supports a given capability.
Returns true for capabilities marked true or "emulated" in the spec.
Returns false for false, "__undefined", or missing capabilities.
Capability names use camelCase strings matching the CCXT spec
(e.g., "fetchTicker", "createOrder").
Examples
CCXT.Exchange.has?(exchange, "fetchTicker")
#=> true
CCXT.Exchange.has?(exchange, "fetchFundingRateHistory")
#=> false
Creates an exchange configuration from an exchange ID and options.
Loads the spec, resolves base URLs (with hostname interpolation and sandbox/testnet switching), and optionally builds credentials.
Options
:api_key- API key string (builds credentials automatically):secret- API secret string (builds credentials automatically):password- API password (OKX, KuCoin):uid- User ID:credentials- Pre-built%CCXT.Credentials{}(overrides key/secret opts):sandbox- Use testnet URLs (default:false):hostname- Override the default hostname:options- Exchange-specific options map
Examples
{:ok, exchange} = CCXT.Exchange.new("bybit")
{:ok, exchange} = CCXT.Exchange.new("okx", api_key: "k", secret: "s", password: "p")
{:error, :missing_secret} = CCXT.Exchange.new("bybit", api_key: "k")
Creates an exchange configuration, raising on error.
Examples
exchange = CCXT.Exchange.new!("bybit")
exchange = CCXT.Exchange.new!("bybit", api_key: "abc", secret: "xyz")
Prepares all compile-time data for the generator macro.
Returns the exchange's tier string, or nil if the spec omits it.
Values mirror priv/priority_tiers.json from ccxt_extract: "tier1",
"tier2", "dex", "tier3", "unclassified". Specs emitted before
ccxt_extract schema 1.8.0 (2026-04-14) have no tier field and return nil.
Examples
CCXT.Exchange.tier(CCXT.Exchange.new!("bybit"))
#=> "tier1"