Important: No default broker tags are set. You may manually specify a broker tag within function arguments if needed.
Forked from krex, a simplified version of the ccxt Python library.
Originally created and maintained by the same contributor, this fork continues active development, building upon the original foundation with enhanced design, unified DEX + CEX support, and fixes for previously unresolved issues.
A high-performance and lightweight Python library for interacting with cryptocurrency exchanges. dcex offers synchronous and asynchronous clients across multiple major exchanges, designed for speed, modularity, and ease of use.
Scope note: dcex focuses on market data, account queries, and trading/order APIs. External withdrawal creation endpoints are not currently wrapped, and options support is limited to exchange-specific APIs rather than the unified Product Table Manager.
pip install dcexor use uv to manage the project:
uv add dceximport dcex
client = dcex.binance()
klines = client.get_klines(product_symbol="BTC-USDT-SWAP", interval="1m")
print(klines)import os
import asyncio
import dcex.async_support as dcex
from dotenv import load_dotenv
load_dotenv()
BINANCE_API_KEY = os.getenv("BINANCE_API_KEY")
BINANCE_API_SECRET = os.getenv("BINANCE_API_SECRET")
async def main():
client = await dcex.binance(
api_key=BINANCE_API_KEY,
api_secret=BINANCE_API_SECRET
)
try:
result = await client.get_income_history()
print(result)
finally:
await client.close()
if __name__ == "__main__":
asyncio.run(main())| Exchange | Sync Support | Async Support |
|---|---|---|
| Binance | Yes | Yes |
| Bybit | Yes | Yes |
| OKX | Yes | Yes |
| BitMart | Yes | Yes |
| BitMEX | Yes | Yes |
| Gate.io | Yes | Yes |
| Hyperliquid | Yes | Yes |
| BingX | Yes | Yes |
| KuCoin | Yes | Yes |
- Product Table Manager for unifying trading instruments across exchanges
- Sync and async API clients with consistent interfaces where available
- Low-overhead HTTP clients for market data, account queries, and trading workflows
- Opt-in live test suites for public, private, stateful, and generated-report endpoints
PTM is a utility that standardizes and unifies trading instrument metadata across different exchanges, making cross-exchange strategy development easier.
It is a table that contains the following columns:
| Column | Description |
|---|---|
| exchange | The exchange name |
| product_symbol | The symbol we use to identify the product, it will be the same in different exchanges. For example, BTC-USDT-SWAP is the same product in Binance and Bybit, which named BTCUSDT in Binance and BTC-USDT-SWAP in OKX. |
| exchange_symbol | The symbol that the exchange actually uses |
| product_type | The normalized product type used by dcex, e.g. spot, swap, futures |
| exchange_type | The exchange-specific product type, e.g. spot, linear, inverse, perpetual, delivery |
| base_currency | The base currency, e.g. BTC |
| quote_currency | The quote currency, e.g. USDT |
| price_precision | The price precision, e.g. 0.000001 |
| size_precision | The size precision, e.g. 0.000001 |
| min_size | The minimum size, e.g. 0.000001 |
| min_notional | The minimum notional, e.g. 0.000001 |
| size_per_contract | The size per contract. Sometimes 1 contract is not the same as 1 unit in exchanges like OKX. |
Options are not currently included in the unified PTM output. Some exchange-specific clients expose option-related parameters or market endpoints, but options are not normalized across exchanges.
In most cases, dcex handles product-symbol mapping internally. If you have a specific use case, you can use ptm to get the information you need.
from dcex.utils.common import Common
from dcex.product_table.manager import ProductTableManager
ptm = ProductTableManager.get_instance(Common.BINANCE)
product_symbol = ptm.get_product_symbol(
exchange=Common.BINANCE,
exchange_symbol="BTCUSDT",
product_type="swap",
)
print(product_symbol)We welcome contributions. Please see our Contributing Guide for details.
The default test suite is offline and does not require exchange API keys or network access:
uv run pytestPublic live exchange tests are opt-in. They use network access but do not require API keys:
uv run pytest -m "live and not private"Private live tests require the relevant exchange API key environment variables. Use not stateful
and not generated for the normal per-exchange key rotation workflow:
uv run pytest tests/sync_support/binance tests/async_support/binance -m "live and private and not stateful and not generated"Stateful tests can change exchange or account settings, such as leverage or position mode. Run them only when that is intentional:
uv run pytest tests/sync_support/okx tests/async_support/okx -m "live and private and stateful"Generated-report tests request server-side report generation or downloadable files, such as OKX monthly statements. Run them separately because they can consume low-frequency report quotas:
uv run pytest tests/sync_support/okx tests/async_support/okx -m "live and private and generated"Examples are under examples/sync and examples/async. They are concise read-only usage examples:
*_public.pyexamples do not require API keys.*_private_readonly.pyexamples require credentials but avoid order placement, cancellations, external withdrawals, transfers, leverage changes, and account-mode changes.- Endpoint validation belongs in
tests, not inexamples.
This project is licensed under the MIT License.
- Issues: Report bugs and request features on GitHub Issues.
- Discussions: Discuss ideas and share your thoughts on GitHub Discussions.
Cryptocurrency trading involves significant risk. This library is provided as-is without any warranty. Users are responsible for their own trading decisions and risk management.