Metadata-Version: 2.4
Name: dcex
Version: 0.42.1
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Rust
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Networking
License-File: LICENSE
License-File: LICENSES/Apache-2.0.txt
License-File: THIRD_PARTY_NOTICES.md
Summary: Rust-backed Python crypto exchange API library for CEX and DEX market data, trading and WebSocket streams (Binance, Bybit, OKX, Hyperliquid and more).
Keywords: crypto,cryptocurrency,exchange,exchange-api,trading,algorithmic-trading,market-data,websocket,asyncio,dex,cex,perpetual-futures,ccxt,binance,bybit,okx,bitget,kraken,mexc,bingx,hyperliquid,lighter,backpack,aster
Author: pg56714
License-Expression: MIT
Requires-Python: >=3.12
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Changelog, https://github.com/pg56714/dcex/blob/main/CHANGELOG.md
Project-URL: Documentation, https://github.com/pg56714/dcex#readme
Project-URL: Homepage, https://github.com/pg56714/dcex
Project-URL: Issues, https://github.com/pg56714/dcex/issues
Project-URL: Repository, https://github.com/pg56714/dcex

# dcex - DEX & CEX trading library

**English** | [繁體中文](README.zh_tw.md)

dcex is a Rust-backed crypto exchange API library with synchronous and asynchronous Python clients and a standalone Rust crate. It covers market data, account queries, order APIs, and public and private WebSocket streams for centralized exchanges (Binance, Bybit, OKX, Bitget, Kraken, MEXC, BingX) and decentralized perpetual exchanges (Hyperliquid, Lighter, Backpack, Aster, Extended, Ondo, Arcus).

**Broker codes:** dcex does not set or attach a broker code or broker tag by default. You can specify one explicitly when the exchange API supports it.

> Forked from [krex](https://github.com/kairosresearchio/krex), a simplified version of the [ccxt](https://github.com/ccxt/ccxt) Python library.

[![Python](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://python.org)
[![Rust](https://img.shields.io/badge/rust-2024-orange.svg)](https://www.rust-lang.org/)
[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![PyPI](https://img.shields.io/pypi/v/dcex)](https://badge.fury.io/py/dcex)
[![Crates.io](https://img.shields.io/crates/v/dcex)](https://crates.io/crates/dcex)
[![Ask DeepWiki](https://img.shields.io/badge/Ask-DeepWiki-blue)](https://deepwiki.com/pg56714/dcex)

## Installation

Python:

```sh
pip install dcex
# or, in a uv-managed project:
uv add dcex
```

Rust:

```sh
cargo add dcex
```

## Key features

- Synchronous and asynchronous Python HTTP clients, plus public and private WebSocket clients.
- HTTP, WebSocket, and signing APIs for direct use from Rust.
- A Product Table Manager (PTM) that normalizes exchange symbols and trading specifications.
- Support for multiple CEX and DEX platforms; available endpoints vary by exchange.

### Compared with ccxt

[ccxt](https://github.com/ccxt/ccxt) offers one unified API across 100+ exchanges. dcex covers fewer exchanges and keeps each exchange's own endpoints instead:

- Exchange-native methods and parameters, with coverage tracked endpoint by endpoint against the official docs.
- Signing, serialization and response validation run in Rust, including DEX signing for Hyperliquid, Lighter and Extended.
- The same core is available from Python (sync and async) and Rust.
- Normalized symbols (`BTC-USDT-SWAP`) and trading specifications through the Product Table Manager.

Documented withdrawal, market-maker and partner endpoints are in scope; current coverage and specification gaps are recorded in the endpoint ledger. API withdrawals have no second confirmation; they execute on submit. Trading API keys should not have withdrawal permission. PTM includes listed options from Binance, Bybit, and OKX; option trading remains exchange-specific.

## Supported exchanges

| Exchange | HTTP Sync | HTTP Async | WS Public | WS Private |
| --- | --- | --- | --- | --- |
| Binance | Yes | Yes | Yes | Yes |
| Bybit | Yes | Yes | Yes | Yes |
| OKX | Yes | Yes | Yes | Yes |
| Bitget | Yes | Yes | Yes | Yes |
| Kraken | Yes | Yes | Yes | Yes |
| MEXC | Yes | Yes | Yes | Yes |
| BingX | Yes | Yes | Yes | Yes |
| Hyperliquid | Yes | Yes | Yes | Yes |
| Lighter (Mainnet + Robinhood) | Yes | Yes | Yes | Yes |
| Backpack | Yes | Yes | Yes | Yes |
| Aster | Yes | Yes | Yes | Yes |
| Extended | Yes | Yes | Yes | Yes |
| Ondo | Yes | Yes | Yes | Yes |
| Arcus | Yes | Yes | Yes | Yes |

Bitget began migrating accounts to UTA on 2026-09-15. Classic-account private endpoints that Bitget rejects for UTA accounts (error 40085) have been removed; public market-data, tax and institutional-loan endpoints that still work remain. Use a UTA account for trading. See the [official UTA upgrade guide](https://www.bitget.com/docs/classic/uta-api-upgrade-guide) and [account settings](https://www.bitget.com/docs/catalog/account/account-settings).

Private WebSocket support includes authenticated or address-scoped user-data streams. Trading WebSocket APIs are available for Binance, Bybit, Bitget, OKX and Kraken Spot; Hyperliquid and Lighter accept signed actions, and Arcus provides signed request construction. Lighter Mainnet and Robinhood use separate credential profiles; select the network per client (Mainnet is the default); see [.env.example](.env.example) and the [Lighter examples](examples/async/lighter_private_readonly.py). Ondo spot currently supports only public market data (depth, trades, symbol_info, history and WS spot channels); Ondo has not published its spot trading API, so private operations such as placing or cancelling orders with a `-SPOT` symbol fail locally without sending a request.

[Endpoint coverage, limitations and verification](docs/endpoint-audit.md).

## Python quick start

Synchronous HTTP:

```python
import dcex

client = dcex.binance()
print(client.get_klines(product_symbol="BTC-USDT-SWAP", interval="1m"))
```

Asynchronous HTTP:

```python
import asyncio
import dcex.async_support as dcex

async def main():
    client = await dcex.binance()
    try:
        print(await client.get_klines(product_symbol="BTC-USDT-SWAP", interval="1m"))
    finally:
        await client.close()

asyncio.run(main())
```

Additional profiles cover Binance Alpha, Aster Prediction and Kraken Spot V1. Bitget SBE returns raw binary frames for caller-side decoding.

Public WebSocket:

```python
import asyncio
from dcex.ws import binance

async def main():
    async with binance.public() as ws:
        await ws.subscribe_agg_trades("BTC-USDT-SPOT")
        print(await ws.recv())

asyncio.run(main())
```

## Product Table Manager

PTM maps normalized `product_symbol` values, such as `BTC-USDT-SWAP`, to exchange-native `exchange_symbol` values and exposes trading metadata. Clients use this mapping where applicable.

| Product | `product_symbol` | Example |
| --- | --- | --- |
| Spot | `BASE-QUOTE-SPOT` | `BTC-USDT-SPOT` |
| Perpetual | `BASE-QUOTE-SWAP` | `BTC-USDT-SWAP` |
| Dated futures | `BASE-QUOTE-YYMMDD-FUTURES` (UTC delivery date) | `BTC-USD-261225-FUTURES` |

| Fields | Meaning |
| --- | --- |
| `exchange`, `product_symbol`, `exchange_symbol` | Exchange and normalized/native symbols |
| `product_type`, `exchange_type` | Normalized and exchange-specific market types |
| `base_currency`, `quote_currency` | Product currencies |
| `price_precision`, `size_precision` | Price and size increments |
| `min_size`, `min_notional` | Minimum size and notional |
| `size_per_contract` | Contract multiplier |

Binance and BingX coin-margined contracts sit in their own `exchange` namespaces, `binance_coinm` and `bingx_coinm` (for example `BTC-USD-SWAP`), so they never collide with USDT-margined products; their coin-margined methods resolve symbols there.

```python
from dcex.product_table.manager import ProductTableManager

table = ProductTableManager.get_instance("binance")
print(table.get_exchange_symbol("binance", "BTC-USDT-SWAP"))
print(table.get_product_symbol("binance", "BTCUSDT", product_type="swap"))
print(table.rows()[0])
```

Hyperliquid loads its first perp DEX, spot and every builder-deployed (HIP-3) perp DEX by default. Pass `perp_dexs` to load only the builder DEXs you trade; names come from `get_perp_dexs`, unknown names are rejected, and asset ids stay the same as with the full table:

```python
from dcex.hyperliquid import Client

client = Client(perp_dexs=["xyz"])
table = ProductTableManager.get_instance("hyperliquid", perp_dexs=["xyz"])
```

## Lighter nonces

Every Lighter transaction method accepts `nonce`. Without it, dcex asks the exchange for the next nonce, which costs one request per transaction. Trading systems usually keep the nonce themselves:

- Read the starting value once per API key with `get_next_nonce(api_key_index=...)`.
- Increment it locally and pass `nonce=` with each transaction, holding a lock if several tasks share the key.
- After a failed transaction or a nonce error, read `get_next_nonce` again; a rejected transaction may not consume its nonce.
- Give each process its own `api_key_index` so their nonces never collide.

## More examples and development

Runnable examples are in [Python sync](examples/sync), [Python async and WebSocket](examples/async), and [Rust](crates/dcex/examples). They focus on public data or read-only account queries. Private HTTP examples require credentials; private stream examples require credentials or a user address.

```sh
uv run python examples/sync/binance_public.py
uv run python examples/async/binance_ws_public.py
cargo run -p dcex --example binance_ws_public
```

For direct Rust usage, see the [crate README](crates/dcex/README.md). The default test suite runs offline with `uv run pytest`; live suites are opt-in. See the [contributing guide](.github/CONTRIBUTING.md) for development and testing details.

This project uses the [MIT License](LICENSE); see the [third-party notices](THIRD_PARTY_NOTICES.md) for additional licenses.

