Short answer: CCXT Pro, the WebSocket part of the CCXT library, is free: since version 1.95, announced on 3 October 2022, it ships inside the MIT-licensed ccxt package as ccxt.pro. In release 4.5.92, current on 6 November 2026, 76 of 104 exchange classes can stream. Methods such as watch_order_book and watch_trades reconnect when called again after a drop, but CCXT does not replay trades sent during the gap.
The CCXT manual, repository and PyPI were read, and the tests below run, on 6 November 2026 with ccxt 4.5.92, aiohttp 3.14.5 and Python 3.11.3 against public Kraken streams without an API key; no order was placed.
It is technical documentation, not a recommendation of any exchange, library or strategy, and automated trading can lose money. Whether you may use an exchange depends on your jurisdiction and its terms. For readers in Turkey: Article 99/A of Capital Markets Law No. 6362 treats activity by foreign crypto-asset platforms directed at Turkish residents as unauthorized.
Is CCXT Pro free? Pricing, license and install
Yes: since version 1.95, CCXT Pro has been part of the free, MIT-licensed ccxt package.
| Question | What the project's own pages say |
|---|---|
| Price | The Pro manual opens by calling CCXT Pro a free part of CCXT. The old ccxt.pro web address now redirects to the merge announcement. Directory listings with monthly plans (USD 29 to 199, seen 6 November 2026) are out of date. |
| Free since | Version 1.95, announced in GitHub issue #15171 on 3 October 2022, when PyPI also received ccxt 1.95.1. Paying subscribers were told to ignore subscription expiry notices. |
| License | MIT, per LICENSE.txt and the PyPI metadata: commercial use is allowed, without warranty. |
| Install | pip install ccxt, then import ccxt.pro. Release 4.5.92 was published on 4 November 2026 and needs Python 3.10 or later. |
pip install ccxtpro | Do not use it. The ccxtpro name on PyPI holds a 2.6 KB placeholder from Igor Kroitor, CCXT's copyright holder, last released on 24 April 2020, whose only module holds a license notice and no code. |
Each exchange's API terms apply on top of the MIT license. Releases are frequent, six between 13 October and 4 November 2026, so pin the version you tested. The CCXT Python guide covers the REST side.
CCXT Pro exchanges: which venues can stream
In ccxt 4.5.92, 76 of the 104 exchange classes have a WebSocket version, but the project's pages give other totals, so check the installed package, not a list.
- The README says the library supports 103 exchange markets and trading APIs; the package lists 104 classes in
ccxt.exchanges. - The Pro manual says 73 exchanges stream;
ccxt.pro.exchangeslists 76. - Support is per method, so read
exchange.hasbefore relying on a stream.
| Class | watchOrderBook | watchTrades | watchTradesForSymbols | unWatchOrderBook | keepAlive (ms) |
|---|---|---|---|---|---|
| kraken | True | True | True | not set | 6,000 |
| okx | True | True | True | True | 18,000 |
| binance | True | True | True | True | 180,000 |
| coinbase | True | True | True | not set, though the method exists | 30,000 |
| bitstamp | True | True | False | True | 30,000 |
A True flag says the method exists in CCXT, not that the venue is open to you. Limits on connections and subscriptions come from each exchange's own documentation, as in the Binance WebSocket guide.
watch_order_book and watch_trades: what each call returns
Each call waits for the next update: watch_order_book returns the book CCXT keeps in memory, and watch_trades returns trades from a fixed-size cache.
- Book depth. Per the manual,
limitgoes to the exchange when it accepts one (some take only values such as 10, 25, 50 or 100) and is applied locally otherwise. It is a maximum, not a guarantee. - New trades only, by default. The manual says
newUpdateswill become the default in the future; in 4.5.92 it is already True in all 76 streaming classes. Eachwatch_tradescall returns only trades that arrived since the previous call. For the sliding cache, create the exchange with{'newUpdates': False}; inparams, Kraken rejected it and the call hung (6 November 2026). - The cache holds 1,000 entries.
tradesLimit,OHLCVLimitandordersLimitdefault to 1,000, must be set inoptionsbefore the first watch call and cannot change during the run.sinceandlimitfilter inside the cache; you cannot page past it. - Book integrity. Where an exchange needs a REST snapshot plus deltas, CCXT fetches it and retries up to
maxRetries, 3 by default. Checksum checks are per exchange: the Kraken class ships with them off, and a source comment says the exchange checksum was not reliable. Checking a book yourself is covered in the WebSocket order book guide.
Synthetic test: a slow reader loses trades silently. CCXT's ArrayCache was created with room for 5 entries, and 8 synthetic trades were added between two reads. getLimit, which watch_trades uses in this mode, reported 8 new trades, but only IDs 4 to 8 were still there, and no error was raised. With the default, the same happens past 1,000 trades between reads, so keep the reading loop fast.
A tested CCXT WebSocket example in Python
The script streams a Kraken order book and trades, cuts its own socket to imitate a network drop, reconnects, backfills missed trades over REST and drops duplicates.
The output below is from a run at 00:03 UTC on 6 November 2026. Aborting the transport uses a private attribute and belongs in a test only. On Python 3.11.3 it may end with a close() error (see Shutdown).
import asyncio, collections, time
import ccxt.pro as ccxtpro
from ccxt.base.errors import NetworkError
SYMBOL, DEPTH = "BTC/USD", 10
drops = 0
def now():
return time.strftime("%H:%M:%S", time.gmtime())
class Seen: # recent trade ids, bounded memory
def __init__(self, size=5000):
self.size, self.order, self.ids = size, collections.deque(), set()
def is_new(self, trade):
tid = trade.get("id")
if not tid: # no id: cannot match, so keep it
return True
if tid in self.ids:
return False
self.order.append(tid)
self.ids.add(tid)
if len(self.order) > self.size:
self.ids.discard(self.order.popleft())
return True
async def retrying(call, max_failures=5):
global drops
for failure in range(max_failures + 1):
try:
return await call() # a new call after an error reconnects
except NetworkError as e: # drop, timeout, checksum error
if failure == max_failures:
raise
drops += 1
print(f"{now()} NetworkError: {e}")
await asyncio.sleep(min(2 ** failure, 30))
async def main(steps=6, drop_at=3):
ex = ccxtpro.kraken() # public streams, no API key
seen, last_ms, seen_drops = Seen(), None, 0
try:
for step in range(steps):
if step == drop_at: # test only: cut the socket abruptly
for client in list(ex.clients.values()):
if client.connection is not None:
client.connection._conn.transport.abort()
print(f"{now()} socket aborted")
book = await retrying(lambda: ex.watch_order_book(SYMBOL, DEPTH))
trades = await retrying(lambda: ex.watch_trades(SYMBOL))
if drops > seen_drops: # reconnected: backfill the gap over REST
seen_drops = drops
if last_ms:
trades = await retrying(lambda: ex.fetch_trades(SYMBOL, since=last_ms)) + trades
fresh = [t for t in trades if seen.is_new(t)]
stamps = [t["timestamp"] for t in fresh if t.get("timestamp")]
last_ms = max(stamps + [last_ms or 0]) or None
bid = book["bids"][0][0] if book["bids"] else None
ask = book["asks"][0][0] if book["asks"] else None
print(f"{now()} bid {bid} ask {ask} trades {len(fresh)} new, {len(trades) - len(fresh)} repeated")
finally:
await ex.close()
if __name__ == "__main__":
asyncio.run(main())
00:03:08 bid 76166.5 ask 76166.6 trades 1 new, 0 repeated
00:03:08 bid 76166.5 ask 76166.6 trades 1 new, 0 repeated
00:03:08 bid 76166.5 ask 76166.6 trades 1 new, 0 repeated
00:03:08 socket aborted
00:03:08 NetworkError: Connection closed by remote server, closing code 1006
00:03:11 bid 76166.5 ask 76166.6 trades 6 new, 2 repeated
00:03:13 bid 76146.2 ask 76146.3 trades 9 new, 3 repeated
00:03:14 bid 76156.4 ask 76156.5 trades 4 new, 0 repeated
- The pending call failed with
NetworkError: Connection closed by remote server, closing code 1006, although the local side cut the socket, so the message does not show who closed it. - After the reconnect, the REST backfill plus the first new stream batch held eight trades: six not seen before and two already seen. The next stream batch held three trades already seen.
Seenremoved all five. Kraken sends a trade snapshot only on request (default false in its v2 documentation, read 6 November 2026), and CCXT does not request one, so these repeats are REST and stream overlap. - In a probe of six forced drops, the first
watch_order_bookcall afterwards still returned a book four times; the error came later. Check the book'stimestampbefore acting on it.
Synthetic helper tests passed: one NetworkError then success returned the result, BadSymbol stopped at once, a sixth network error in a row was raised, and trades with an empty or missing ID never counted as duplicates. fetch_trades returns one page, so a longer gap needs pagination with since.
CCXT Pro reconnect: what the library does and does not do
CCXT Pro reconnects only when your code calls a watch method again after an error, which is the loop its manual describes, and it replays nothing.
| Event | What CCXT does |
|---|---|
| Connection drops mid-session | Rejects every pending call with NetworkError and discards the connection. The next watch call dials again without delay and sends only its own subscription. |
| Dial fails | Per-address backoff of 0.1 × 2n seconds, from 0.2 up to a 30-second cap, or longer if the failed handshake carried Retry-After. A successful connection clears it. |
| No connection within 10 seconds | RequestTimeout (connectionTimeout is 10,000 ms). |
| Pongs stop | RequestTimeout after more than two keepAlive intervals without one: at least 12 seconds for Kraken and 6 minutes for Binance with the defaults above. |
| Book checksum or sequence error | ChecksumError or InvalidNonce, both subclasses of NetworkError, so a retry loop treats them like a drop. |
Streams that shared the connection come back one by one, each only when its own watch call runs again. Trades sent during the gap are lost unless you backfill them, and trades a venue resends after resubscribing arrive as new, so deduplicate by ID. Other errors, such as BadSymbol or AuthenticationError, will not fix themselves: stop and alert. Heartbeats without CCXT are covered in the WebSocket heartbeat and reconnect guide, and CCXT's error classes in CCXT rate limit and error handling.
Where CCXT Pro fails in a long-running bot
Most failures come from the code around the library: shutdown, unsubscribing and orders whose outcome is unknown.
- Shutdown. Always
await exchange.close(), or CCXT warns about unreleased resources. On Python 3.11.3,close()raised anAttributeErrorinside asyncio's SSL layer in three of four runs of the example on 6 November 2026 and one of three without the forced drop. The cause is a CPython bug fixed in 3.11.4: use a current patch release and test shutdown on it. - Unsubscribing. The manual describes unWatch methods as stopping the background subscription a watch call starts, and Kraken defines no
unWatchOrderBookin 4.5.92. Closing the instance ends the stream. - Orders over WebSocket.
createOrderWsis True for kraken, okx and binance in 4.5.92. A drop during an order request leaves its outcome unknown: look the order up before sending it again, and test on a testnet first.
CCXT alternatives: official exchange SDKs and raw WebSockets
For a single venue, the alternative to CCXT Pro is that venue's own WebSocket API, used directly or through its official SDK; neither is better in general.
| Question | CCXT Pro | Official SDK or raw WebSocket |
|---|---|---|
| Venues | One interface for 76 classes | One venue each |
| Venue-specific options | Unified structures; extras go through params | Everything the venue documents |
| Reconnect and book sync | Built in, with the limits above | Your code, or whatever the SDK provides |
| License | MIT | Check each SDK's own license |
Guides on this site describe the native APIs of Kraken and OKX, and the open-source crypto trading bot guide covers frameworks that use CCXT. For integration work in general, see Fincode's exchange API integration page; naming these exchanges here does not mean Fincode integrates them or has built on them.
Frequently asked questions
Is CCXT Pro free?
Yes. Since version 1.95, announced on 3 October 2022, CCXT Pro has been part of the free, MIT-licensed ccxt package.
Do I need pip install ccxtpro?
No. Install ccxt and import ccxt.pro. The ccxtpro name on PyPI is a 2.6 KB placeholder last released in April 2020.
Where is the CCXT GitHub repository?
At github.com/ccxt/ccxt, under the MIT license, with the general and CCXT Pro manuals in its wiki.
Does CCXT Pro reconnect automatically?
Only when you call a watch method again after the error. Each stream resubscribes on its own call, and CCXT does not replay trades sent during the gap.
Why does watch_trades return only one or two trades?
In ccxt 4.5.92 newUpdates is on by default, so each call returns only trades since the previous call. Set newUpdates to False in the exchange constructor for the cached window of up to 1,000 trades.
Sources
- CCXT repository on GitHub, README (supported exchanges, install) (opens in a new tab)
- CCXT Pro manual (GitHub wiki): streaming specifics, caching, newUpdates, watchOrderBook (opens in a new tab)
- CCXT issue 15171: CCXT Pro Websockets merged with CCXT (3 October 2022) (opens in a new tab)
- CCXT LICENSE.txt (MIT) (opens in a new tab)
- PyPI: ccxt release history and metadata (4.5.92, 4 November 2026) (opens in a new tab)
- PyPI: ccxtpro placeholder package (1.0.1, April 2020) (opens in a new tab)
- CCXT 4.5.92 source: async Exchange base class (watch, dial backoff, on_close) (opens in a new tab)
- CCXT 4.5.92 source: WebSocket client (connection timeout, keepalive) (opens in a new tab)
- CCXT 4.5.92 source: WebSocket cache (ArrayCache) (opens in a new tab)
- CCXT 4.5.92 source: Kraken Pro class (order book checksum option) (opens in a new tab)
- Kraken WebSocket v2 documentation: trade channel (snapshot parameter) (opens in a new tab)
- CPython 3.11 commit for gh-98539: make the SSL transport's abort() safe to call when closed (14 May 2023) (opens in a new tab)
- Capital Markets Law No. 6362, Article 99/A (Turkish) (opens in a new tab)
This guide is general information about software and markets, not investment, legal or tax advice. Automated trading can lose money, past or backtested performance does not guarantee future results, and the rules that apply depend on your jurisdiction and your exchange's terms. Sources, checks and corrections: see the editorial policy.