New to Claude Skills? Learn how to install them โ†’

ccxt on GitHub

CCXT for PHP

Free

Integrate cryptocurrency exchanges seamlessly in PHP.

by ccxt43.6k stars on ccxt/ccxt
Updated Aug 10, 2026
Get this skill

Free ยท Opens the source repo

What CCXT for PHP does

CCXT for PHP is a powerful library designed for PHP developers looking to integrate cryptocurrency exchange functionalities into their applications. This library provides comprehensive support for both REST and WebSocket APIs, allowing for both synchronous and asynchronous operations. Whether you are building trading bots, web applications, or any project that requires interaction with cryptocurrency exchanges, CCXT simplifies the process of connecting to various platforms, fetching market data, and managing orders.

Installation is straightforward via Composer, ensuring that you can quickly get started with minimal setup. CCXT requires certain PHP extensions, such as cURL and mbstring, to function properly, and it also supports ReactPHP for asynchronous operations. The library covers a wide range of operations including loading markets, fetching tickers, managing orders, and monitoring balances, making it a versatile tool for developers.

For real-time data, CCXT offers WebSocket support, enabling developers to receive live updates on market prices and order books. This is particularly beneficial for applications that require continuous data streams, such as trading platforms or market analysis tools. The library is compatible with PHP 8.1 and above, ensuring that you can leverage the latest PHP features while developing your applications.

In summary, CCXT for PHP is an essential tool for developers working in the cryptocurrency space, providing the necessary functionalities to interact with exchanges efficiently and effectively. Its support for both synchronous and asynchronous operations makes it suitable for a variety of use cases, from simple data retrieval to complex trading strategies.

When to use it

Use this skill when developing PHP applications that require interaction with cryptocurrency exchanges, such as trading bots or market analysis tools.

When not to use it

This skill may not be suitable for applications that do not require real-time data or those built in languages other than PHP.

What you can build with it

Building a Trading Bot

Develop a trading bot that connects to various cryptocurrency exchanges, fetches market data, and places orders based on predefined strategies.

Real-time Market Monitoring

Create an application that streams live market data using WebSocket APIs to provide users with up-to-date information on cryptocurrency prices.

Portfolio Management Application

Build a web application that allows users to manage their cryptocurrency portfolios, track balances, and view transaction histories.

How to install CCXT for PHP

View source

1. Install with the skills CLI

npx skills add ccxt/ccxt/ccxt-php --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by ccxt

CCXT for PHP

A comprehensive guide to using CCXT in PHP projects for cryptocurrency exchange integration.

Installation

Via Composer (REST and WebSocket)

composer require ccxt/ccxt

Required PHP Extensions

  • cURL
  • mbstring (UTF-8)
  • PCRE
  • iconv
  • gmp (for some exchanges)

Optional for Async/WebSocket

  • ReactPHP (installed automatically with ccxt)

Quick Start

REST API - Synchronous

<?php
date_default_timezone_set('UTC');  // Required!
require_once 'vendor/autoload.php';

$exchange = new \ccxt\binance();
$exchange->load_markets();
$ticker = $exchange->fetch_ticker('BTC/USDT');
print_r($ticker);

REST API - Asynchronous (ReactPHP)

<?php
use function React\Async\await;

date_default_timezone_set('UTC');
require_once 'vendor/autoload.php';

$exchange = new \ccxt\async\binance();
$ticker = await($exchange->fetch_ticker('BTC/USDT'));
print_r($ticker);

WebSocket API - Real-time Updates

<?php
use function React\Async\await;
use function React\Async\async;

date_default_timezone_set('UTC');
require_once 'vendor/autoload.php';

$exchange = new \ccxt\pro\binance();

while (true) {
    $ticker = await($exchange->watch_ticker('BTC/USDT'));
    print_r($ticker);  // Live updates!
}

await($exchange->close());

REST vs WebSocket

ModeRESTWebSocket
Sync\ccxt\binance()(WebSocket requires async)
Async\ccxt\async\binance()\ccxt\pro\binance()
FeatureREST APIWebSocket API
Use forOne-time queries, placing ordersReal-time monitoring, live price feeds
Method prefixfetch_* (fetch_ticker, fetch_order_book)watch_* (watch_ticker, watch_order_book)
SpeedSlower (HTTP request/response)Faster (persistent connection)
Rate limitsStrict (1-2 req/sec)More lenient (continuous stream)
Best forTrading, account managementPrice monitoring, arbitrage detection

Creating Exchange Instance

REST API - Synchronous

<?php
date_default_timezone_set('UTC');
require_once 'vendor/autoload.php';

// Public API (no authentication)
$exchange = new \ccxt\binance([
    'enableRateLimit' => true  // Recommended!
]);

// Private API (with authentication)
$exchange = new \ccxt\binance([
    'apiKey' => 'YOUR_API_KEY',
    'secret' => 'YOUR_SECRET',
    'enableRateLimit' => true
]);

REST API - Asynchronous

<?php
use function React\Async\await;

$exchange = new \ccxt\async\binance([
    'enableRateLimit' => true
]);

$ticker = await($exchange->fetch_ticker('BTC/USDT'));

WebSocket API

<?php
use function React\Async\await;

// Public WebSocket
$exchange = new \ccxt\pro\binance();

// Private WebSocket (with authentication)
$exchange = new \ccxt\pro\binance([
    'apiKey' => 'YOUR_API_KEY',
    'secret' => 'YOUR_SECRET'
]);

// Always close when done
await($exchange->close());

Common REST Operations

Loading Markets

// Load all available trading pairs
$exchange->load_markets();

// Access market information
$btc_market = $exchange->market('BTC/USDT');
print_r($btc_market['limits']['amount']['min']);  // Minimum order amount

Fetching Ticker

// Single ticker
$ticker = $exchange->fetch_ticker('BTC/USDT');
print_r($ticker['last']);      // Last price
print_r($ticker['bid']);       // Best bid
print_r($ticker['ask']);       // Best ask
print_r($ticker['volume']);    // 24h volume

// Multiple tickers (if supported)
$tickers = $exchange->fetch_tickers(['BTC/USDT', 'ETH/USDT']);

Fetching Order Book

// Full orderbook
$orderbook = $exchange->fetch_order_book('BTC/USDT');
print_r($orderbook['bids'][0]);  // [price, amount]
print_r($orderbook['asks'][0]);  // [price, amount]

// Limited depth
$orderbook = $exchange->fetch_order_book('BTC/USDT', 5);  // Top 5 levels

Creating Orders

Limit Order

// Buy limit order
$order = $exchange->create_limit_buy_order('BTC/USDT', 0.01, 50000);
print_r($order['id']);

// Sell limit order
$order = $exchange->create_limit_sell_order('BTC/USDT', 0.01, 60000);

// Generic limit order
$order = $exchange->create_order('BTC/USDT', 'limit', 'buy', 0.01, 50000);

Market Order

// Buy market order
$order = $exchange->create_market_buy_order('BTC/USDT', 0.01);

// Sell market order
$order = $exchange->create_market_sell_order('BTC/USDT', 0.01);

// Generic market order
$order = $exchange->create_order('BTC/USDT', 'market', 'sell', 0.01);

Fetching Balance

$balance = $exchange->fetch_balance();
print_r($balance['BTC']['free']);   // Available balance
print_r($balance['BTC']['used']);   // Balance in orders
print_r($balance['BTC']['total']);  // Total balance

Fetching Orders

// Open orders
$open_orders = $exchange->fetch_open_orders('BTC/USDT');

// Closed orders
$closed_orders = $exchange->fetch_closed_orders('BTC/USDT');

// All orders (open + closed)
$all_orders = $exchange->fetch_orders('BTC/USDT');

// Single order by ID
$order = $exchange->fetch_order($order_id, 'BTC/USDT');

Fetching Trades

// Recent public trades
$trades = $exchange->fetch_trades('BTC/USDT', null, 10);

// Your trades (requires authentication)
$my_trades = $exchange->fetch_my_trades('BTC/USDT');

Canceling Orders

// Cancel single order
$exchange->cancel_order($order_id, 'BTC/USDT');

// Cancel all orders for a symbol
$exchange->cancel_all_orders('BTC/USDT');

WebSocket Operations (Real-time)

Watching Ticker (Live Price Updates)

<?php
use function React\Async\await;

$exchange = new \ccxt\pro\binance();

while (true) {
    $ticker = await($exchange->watch_ticker('BTC/USDT'));
    print_r($ticker['last']);
}

await($exchange->close());

Watching Order Book (Live Depth Updates)

<?php
use function React\Async\await;

$exchange = new \ccxt\pro\binance();

while (true) {
    $orderbook = await($exchange->watch_order_book('BTC/USDT'));
    print_r('Best bid: ' . $orderbook['bids'][0][0]);
    print_r('Best ask: ' . $orderbook['asks'][0][0]);
}

await($exchange->close());

Watching Trades (Live Trade Stream)

<?php
use function React\Async\await;

$exchange = new \ccxt\pro\binance();

while (true) {
    $trades = await($exchange->watch_trades('BTC/USDT'));
    foreach ($trades as $trade) {
        print_r($trade['price'] . ' ' . $trade['amount'] . ' ' . $trade['side']);
    }
}

await($exchange->close());

Watching Your Orders (Live Order Updates)

<?php
use function React\Async\await;

$exchange = new \ccxt\pro\binance([
    'apiKey' => 'YOUR_API_KEY',
    'secret' => 'YOUR_SECRET'
]);

while (true) {
    $orders = await($exchange->watch_orders('BTC/USDT'));
    foreach ($orders as $order) {
        print_r($order['id'] . ' ' . $order['status'] . ' ' . $order['filled']);
    }
}

await($exchange->close());

Watching Balance (Live Balance Updates)

<?php
use function React\Async\await;

$exchange = new \ccxt\pro\binance([
    'apiKey' => 'YOUR_API_KEY',
    'secret' => 'YOUR_SECRET'
]);

while (true) {
    $balance = await($exchange->watch_balance());
    print_r('BTC: ' . $balance['BTC']['total']);
}

await($exchange->close());

Complete Method Reference

Market Data Methods

Tickers & Prices

  • fetchTicker(symbol) - Fetch ticker for one symbol
  • fetchTickers([symbols]) - Fetch multiple tickers at once
  • fetchBidsAsks([symbols]) - Fetch best bid/ask for multiple symbols
  • fetchLastPrices([symbols]) - Fetch last prices
  • fetchMarkPrices([symbols]) - Fetch mark prices (derivatives)

Order Books

  • fetchOrderBook(symbol, limit) - Fetch order book
  • fetchOrderBooks([symbols]) - Fetch multiple order books
  • fetchL2OrderBook(symbol) - Fetch level 2 order book
  • fetchL3OrderBook(symbol) - Fetch level 3 order book (if supported)

Trades

  • fetchTrades(symbol, since, limit) - Fetch public trades
  • fetchMyTrades(symbol, since, limit) - Fetch your trades (auth required)
  • fetchOrderTrades(orderId, symbol) - Fetch trades for specific order

OHLCV (Candlesticks)

  • fetchOHLCV(symbol, timeframe, since, limit) - Fetch candlestick data
  • fetchIndexOHLCV(symbol, timeframe) - Fetch index price OHLCV
  • fetchMarkOHLCV(symbol, timeframe) - Fetch mark price OHLCV
  • fetchPremiumIndexOHLCV(symbol, timeframe) - Fetch premium index OHLCV

Account & Balance

  • fetchBalance() - Fetch account balance (auth required)
  • fetchAccounts() - Fetch sub-accounts
  • fetchLedger(code, since, limit) - Fetch ledger history
  • fetchLedgerEntry(id, code) - Fetch specific ledger entry
  • fetchTransactions(code, since, limit) - Fetch transactions
  • fetchDeposits(code, since, limit) - Fetch deposit history
  • fetchWithdrawals(code, since, limit) - Fetch withdrawal history
  • fetchDepositsWithdrawals(code, since, limit) - Fetch both deposits and withdrawals

Trading Methods

Creating Orders

  • createOrder(symbol, type, side, amount, price, params) - Create order (generic)
  • createLimitOrder(symbol, side, amount, price) - Create limit order
  • createMarketOrder(symbol, side, amount) - Create market order
  • createLimitBuyOrder(symbol, amount, price) - Buy limit order
  • createLimitSellOrder(symbol, amount, price) - Sell limit order
  • createMarketBuyOrder(symbol, amount) - Buy market order
  • createMarketSellOrder(symbol, amount) - Sell market order
  • createMarketBuyOrderWithCost(symbol, cost) - Buy with specific cost
  • createStopLimitOrder(symbol, side, amount, price, stopPrice) - Stop-limit order
  • createStopMarketOrder(symbol, side, amount, stopPrice) - Stop-market order
  • createStopLossOrder(symbol, side, amount, stopPrice) - Stop-loss order
  • createTakeProfitOrder(symbol, side, amount, takeProfitPrice) - Take-profit order
  • createTrailingAmountOrder(symbol, side, amount, trailingAmount) - Trailing stop
  • createTrailingPercentOrder(symbol, side, amount, trailingPercent) - Trailing stop %
  • createTriggerOrder(symbol, side, amount, triggerPrice) - Trigger order
  • createPostOnlyOrder(symbol, side, amount, price) - Post-only order
  • createReduceOnlyOrder(symbol, side, amount, price) - Reduce-only order
  • createOrders([orders]) - Create multiple orders at once
  • createOrderWithTakeProfitAndStopLoss(symbol, type, side, amount, price, tpPrice, slPrice) - OCO order

Managing Orders

  • fetchOrder(orderId, symbol) - Fetch single order
  • fetchOrders(symbol, since, limit) - Fetch all orders
  • fetchOpenOrders(symbol, since, limit) - Fetch open orders
  • fetchClosedOrders(symbol, since, limit) - Fetch closed orders
  • fetchCanceledOrders(symbol, since, limit) - Fetch canceled orders
  • fetchOpenOrder(orderId, symbol) - Fetch specific open order
  • fetchOrdersByStatus(status, symbol) - Fetch orders by status
  • cancelOrder(orderId, symbol) - Cancel single order
  • cancelOrders([orderIds], symbol) - Cancel multiple orders
  • cancelAllOrders(symbol) - Cancel all orders for symbol
  • editOrder(orderId, symbol, type, side, amount, price) - Modify order

Margin & Leverage

  • fetchBorrowRate(code) - Fetch borrow rate for margin
  • fetchBorrowRates([codes]) - Fetch multiple borrow rates
  • fetchBorrowRateHistory(code, since, limit) - Historical borrow rates
  • fetchCrossBorrowRate(code) - Cross margin borrow rate
  • fetchIsolatedBorrowRate(symbol, code) - Isolated margin borrow rate
  • borrowMargin(code, amount, symbol) - Borrow margin
  • repayMargin(code, amount, symbol) - Repay margin
  • fetchLeverage(symbol) - Fetch leverage
  • setLeverage(leverage, symbol) - Set leverage
  • fetchLeverageTiers(symbols) - Fetch leverage tiers
  • fetchMarketLeverageTiers(symbol) - Leverage tiers for market
  • setMarginMode(marginMode, symbol) - Set margin mode (cross/isolated)
  • fetchMarginMode(symbol) - Fetch margin mode

Derivatives & Futures

Positions

  • fetchPosition(symbol) - Fetch single position
  • fetchPositions([symbols]) - Fetch all positions
  • fetchPositionsForSymbol(symbol) - Fetch positions for symbol
  • fetchPositionHistory(symbol, since, limit) - Position history
  • fetchPositionsHistory(symbols, since, limit) - Multiple position history
  • fetchPositionMode(symbol) - Fetch position mode (one-way/hedge)
  • setPositionMode(hedged, symbol) - Set position mode
  • closePosition(symbol, side) - Close position
  • closeAllPositions() - Close all positions

Funding & Settlement

  • fetchFundingRate(symbol) - Current funding rate
  • fetchFundingRates([symbols]) - Multiple funding rates
  • fetchFundingRateHistory(symbol, since, limit) - Funding rate history
  • fetchFundingHistory(symbol, since, limit) - Your funding payments
  • fetchFundingInterval(symbol) - Funding interval
  • fetchSettlementHistory(symbol, since, limit) - Settlement history
  • fetchMySettlementHistory(symbol, since, limit) - Your settlement history

Open Interest & Liquidations

  • fetchOpenInterest(symbol) - Open interest for symbol
  • fetchOpenInterests([symbols]) - Multiple open interests
  • fetchOpenInterestHistory(symbol, timeframe, since, limit) - OI history
  • fetchLiquidations(symbol, since, limit) - Public liquidations
  • fetchMyLiquidations(symbol, since, limit) - Your liquidations

Options

  • fetchOption(symbol) - Fetch option info
  • fetchOptionChain(code) - Fetch option chain
  • fetchGreeks(symbol) - Fetch option greeks
  • fetchVolatilityHistory(code, since, limit) - Volatility history
  • fetchUnderlyingAssets() - Fetch underlying assets

Fees & Limits

  • fetchTradingFee(symbol) - Trading fee for symbol
  • fetchTradingFees([symbols]) - Trading fees for multiple symbols
  • fetchTradingLimits([symbols]) - Trading limits
  • fetchTransactionFee(code) - Transaction/withdrawal fee
  • fetchTransactionFees([codes]) - Multiple transaction fees
  • fetchDepositWithdrawFee(code) - Deposit/withdrawal fee
  • fetchDepositWithdrawFees([codes]) - Multiple deposit/withdraw fees

Deposits & Withdrawals

  • fetchDepositAddress(code, params) - Get deposit address
  • fetchDepositAddresses([codes]) - Multiple deposit addresses
  • fetchDepositAddressesByNetwork(code) - Addresses by network
  • createDepositAddress(code, params) - Create new deposit address
  • fetchDeposit(id, code) - Fetch single deposit
  • fetchWithdrawal(id, code) - Fetch single withdrawal
  • fetchWithdrawAddresses(code) - Fetch withdrawal addresses
  • fetchWithdrawalWhitelist(code) - Fetch whitelist
  • withdraw(code, amount, address, tag, params) - Withdraw funds
  • deposit(code, amount, params) - Deposit funds (if supported)

Transfer & Convert

  • transfer(code, amount, fromAccount, toAccount) - Internal transfer
  • fetchTransfer(id, code) - Fetch transfer info
  • fetchTransfers(code, since, limit) - Fetch transfer history
  • fetchConvertCurrencies() - Currencies available for convert
  • fetchConvertQuote(fromCode, toCode, amount) - Get conversion quote
  • createConvertTrade(fromCode, toCode, amount) - Execute conversion
  • fetchConvertTrade(id) - Fetch convert trade
  • fetchConvertTradeHistory(code, since, limit) - Convert history

Market Info

  • fetchMarkets() - Fetch all markets
  • fetchCurrencies() - Fetch all currencies
  • fetchTime() - Fetch exchange server time
  • fetchStatus() - Fetch exchange status
  • fetchBorrowInterest(code, symbol, since, limit) - Borrow interest paid
  • fetchLongShortRatio(symbol, timeframe, since, limit) - Long/short ratio
  • fetchLongShortRatioHistory(symbol, timeframe, since, limit) - L/S ratio history

WebSocket Methods (ccxt.pro)

All REST methods have WebSocket equivalents with watch* prefix:

Real-time Market Data

  • watchTicker(symbol) - Watch single ticker
  • watchTickers([symbols]) - Watch multiple tickers
  • watchOrderBook(symbol) - Watch order book updates
  • watchOrderBookForSymbols([symbols]) - Watch multiple order books
  • watchTrades(symbol) - Watch public trades
  • watchOHLCV(symbol, timeframe) - Watch candlestick updates
  • watchBidsAsks([symbols]) - Watch best bid/ask

Real-time Account Data (Auth Required)

  • watchBalance() - Watch balance updates
  • watchOrders(symbol) - Watch your order updates
  • watchMyTrades(symbol) - Watch your trade updates
  • watchPositions([symbols]) - Watch position updates
  • watchPositionsForSymbol(symbol) - Watch positions for symbol

Authentication Required

Methods marked with ๐Ÿ”’ require API credentials:

  • All create* methods (creating orders, addresses)
  • All cancel* methods (canceling orders)
  • All edit* methods (modifying orders)
  • All fetchMy* methods (your trades, orders)
  • fetchBalance, fetchLedger, fetchAccounts
  • withdraw, transfer, deposit
  • Margin/leverage methods
  • Position methods
  • watchBalance, watchOrders, watchMyTrades, watchPositions

Checking Method Availability

Not all exchanges support all methods. Check before using:

// Check if method is supported
if (exchange.has['fetchOHLCV']) {
    const candles = await exchange.fetchOHLCV('BTC/USDT', '1h')
}

// Check multiple capabilities
console.log(exchange.has)
// {
//   fetchTicker: true,
//   fetchOHLCV: true,
//   fetchMyTrades: true,
//   fetchPositions: false,
//   ...
// }

Method Naming Convention

  • fetch* - REST API methods (HTTP requests)
  • watch* - WebSocket methods (real-time streams)
  • create* - Create new resources (orders, addresses)
  • cancel* - Cancel existing resources
  • edit* - Modify existing resources
  • set* - Configure settings (leverage, margin mode)
  • *Ws suffix - WebSocket variant (some exchanges)

Proxy Configuration

CCXT supports HTTP, HTTPS, and SOCKS proxies for both REST and WebSocket connections.

Setting Proxy

// HTTP Proxy
exchange.httpProxy = 'http://your-proxy-host:port'

// HTTPS Proxy  
exchange.httpsProxy = 'https://your-proxy-host:port'

// SOCKS Proxy
exchange.socksProxy = 'socks://your-proxy-host:port'

// Proxy with authentication
exchange.httpProxy = 'http://user:pass@proxy-host:port'

Proxy for WebSocket

WebSocket connections also respect proxy settings:

exchange.httpsProxy = 'https://proxy:8080'
// WebSocket connections will use this proxy

Testing Proxy Connection

exchange.httpProxy = 'http://localhost:8080'
try {
    await exchange.fetchTicker('BTC/USDT')
    console.log('Proxy working!')
} catch (error) {
    console.error('Proxy connection failed:', error)
}

WebSocket-Specific Methods

Some exchanges provide WebSocket variants of REST methods for faster order placement and management. These use the *Ws suffix:

Trading via WebSocket

Creating Orders:

  • createOrderWs - Create order via WebSocket (faster than REST)
  • createLimitOrderWs - Create limit order via WebSocket
  • createMarketOrderWs - Create market order via WebSocket
  • createLimitBuyOrderWs - Buy limit order via WebSocket
  • createLimitSellOrderWs - Sell limit order via WebSocket
  • createMarketBuyOrderWs - Buy market order via WebSocket
  • createMarketSellOrderWs - Sell market order via WebSocket
  • createStopLimitOrderWs - Stop-limit order via WebSocket
  • createStopMarketOrderWs - Stop-market order via WebSocket
  • createStopLossOrderWs - Stop-loss order via WebSocket
  • createTakeProfitOrderWs - Take-profit order via WebSocket
  • createTrailingAmountOrderWs - Trailing stop via WebSocket
  • createTrailingPercentOrderWs - Trailing stop % via WebSocket
  • createPostOnlyOrderWs - Post-only order via WebSocket
  • createReduceOnlyOrderWs - Reduce-only order via WebSocket

Managing Orders:

  • editOrderWs - Edit order via WebSocket
  • cancelOrderWs - Cancel order via WebSocket (faster than REST)
  • cancelOrdersWs - Cancel multiple orders via WebSocket
  • cancelAllOrdersWs - Cancel all orders via WebSocket

Fetching Data:

  • fetchOrderWs - Fetch order via WebSocket
  • fetchOrdersWs - Fetch orders via WebSocket
  • fetchOpenOrdersWs - Fetch open orders via WebSocket
  • fetchClosedOrdersWs - Fetch closed orders via WebSocket
  • fetchMyTradesWs - Fetch your trades via WebSocket
  • fetchBalanceWs - Fetch balance via WebSocket
  • fetchPositionWs - Fetch position via WebSocket
  • fetchPositionsWs - Fetch positions via WebSocket
  • fetchPositionsForSymbolWs - Fetch positions for symbol via WebSocket
  • fetchTradingFeesWs - Fetch trading fees via WebSocket

When to Use WebSocket Methods

Use *Ws methods when:

  • You need faster order placement (lower latency)
  • You're already connected via WebSocket
  • You want to reduce REST API rate limit usage
  • Trading strategies require sub-100ms latency

Use REST methods when:

  • You need guaranteed execution confirmation
  • You're making one-off requests
  • The exchange doesn't support the WebSocket variant
  • You need detailed error responses

Example: Order Placement Comparison

REST API (slower, more reliable):

const order = await exchange.createOrder('BTC/USDT', 'limit', 'buy', 0.01, 50000)

WebSocket API (faster, lower latency):

const order = await exchange.createOrderWs('BTC/USDT', 'limit', 'buy', 0.01, 50000)

Checking WebSocket Method Availability

Not all exchanges support WebSocket trading methods:

if (exchange.has['createOrderWs']) {
    // Exchange supports WebSocket order creation
    const order = await exchange.createOrderWs('BTC/USDT', 'limit', 'buy', 0.01, 50000)
} else {
    // Fall back to REST
    const order = await exchange.createOrder('BTC/USDT', 'limit', 'buy', 0.01, 50000)
}

Authentication

Setting API Keys

<?php
// During instantiation (recommended)
$exchange = new \ccxt\binance([
    'apiKey' => getenv('BINANCE_API_KEY'),
    'secret' => getenv('BINANCE_SECRET'),
    'enableRateLimit' => true
]);

// After instantiation
$exchange->apiKey = getenv('BINANCE_API_KEY');
$exchange->secret = getenv('BINANCE_SECRET');

Testing Authentication

try {
    $balance = $exchange->fetch_balance();
    print_r('Authentication successful!');
} catch (\ccxt\AuthenticationError $e) {
    print_r('Invalid API credentials');
}

Error Handling

Exception Hierarchy

BaseError
โ”œโ”€ NetworkError (recoverable - retry)
โ”‚  โ”œโ”€ RequestTimeout
โ”‚  โ”œโ”€ ExchangeNotAvailable
โ”‚  โ”œโ”€ RateLimitExceeded
โ”‚  โ””โ”€ DDoSProtection
โ””โ”€ ExchangeError (non-recoverable - don't retry)
   โ”œโ”€ AuthenticationError
   โ”œโ”€ InsufficientFunds
   โ”œโ”€ InvalidOrder
   โ””โ”€ NotSupported

Basic Error Handling

<?php
try {
    $ticker = $exchange->fetch_ticker('BTC/USDT');
} catch (\ccxt\NetworkError $e) {
    echo 'Network error - retry: ' . $e->getMessage();
} catch (\ccxt\ExchangeError $e) {
    echo 'Exchange error - do not retry: ' . $e->getMessage();
} catch (\Exception $e) {
    echo 'Unknown error: ' . $e->getMessage();
}

Specific Exception Handling

<?php
try {
    $order = $exchange->create_order('BTC/USDT', 'limit', 'buy', 0.01, 50000);
} catch (\ccxt\InsufficientFunds $e) {
    echo 'Not enough balance';
} catch (\ccxt\InvalidOrder $e) {
    echo 'Invalid order parameters';
} catch (\ccxt\RateLimitExceeded $e) {
    echo 'Rate limit hit - wait before retrying';
    sleep(1);  // Wait 1 second
} catch (\ccxt\AuthenticationError $e) {
    echo 'Check your API credentials';
}

Retry Logic for Network Errors

<?php
function fetch_with_retry($exchange, $max_retries = 3) {
    for ($i = 0; $i < $max_retries; $i++) {
        try {
            return $exchange->fetch_ticker('BTC/USDT');
        } catch (\ccxt\NetworkError $e) {
            if ($i < $max_retries - 1) {
                echo "Retry " . ($i + 1) . "/$max_retries\n";
                sleep(1 * ($i + 1));  // Exponential backoff
            } else {
                throw $e;
            }
        }
    }
}

Rate Limiting

Built-in Rate Limiter (Recommended)

$exchange = new \ccxt\binance([
    'enableRateLimit' => true  // Automatically throttles requests
]);

Manual Delays

$exchange->fetch_ticker('BTC/USDT');
usleep($exchange->rateLimit * 1000);  // Convert ms to microseconds
$exchange->fetch_ticker('ETH/USDT');

Checking Rate Limit

print_r($exchange->rateLimit);  // Milliseconds between requests

Common Pitfalls

Forgetting Timezone Setting

// Wrong - will cause errors
<?php
require_once 'vendor/autoload.php';
$exchange = new \ccxt\binance();  // ERROR!

// Correct
<?php
date_default_timezone_set('UTC');  // Required!
require_once 'vendor/autoload.php';
$exchange = new \ccxt\binance();

Wrong Namespace Format

// Wrong - missing leading backslash
$exchange = new ccxt\binance();  // May fail!

// Correct
$exchange = new \ccxt\binance();  // Leading backslash!

Using REST for Real-time Monitoring

// Wrong - wastes rate limits
while (true) {
    $ticker = $exchange->fetch_ticker('BTC/USDT');  // REST
    print_r($ticker['last']);
    sleep(1);
}

// Correct - use WebSocket
use function React\Async\await;
$exchange = new \ccxt\pro\binance();
while (true) {
    $ticker = await($exchange->watch_ticker('BTC/USDT'));  // WebSocket
    print_r($ticker['last']);
}

Not Closing WebSocket Connections

// Wrong - memory leak
$exchange = new \ccxt\pro\binance();
$ticker = await($exchange->watch_ticker('BTC/USDT'));
// Forgot to close!

// Correct
$exchange = new \ccxt\pro\binance();
try {
    while (true) {
        $ticker = await($exchange->watch_ticker('BTC/USDT'));
    }
} finally {
    await($exchange->close());
}

Not Checking PHP Extensions

// Check required extensions before running
<?php
$required = ['curl', 'mbstring', 'iconv', 'gmp'];
foreach ($required as $ext) {
    if (!extension_loaded($ext)) {
        die("Error: $ext extension is not loaded\n");
    }
}

Troubleshooting

Common Issues

1. "date_default_timezone_get(): Invalid date.timezone"

  • Solution: Add date_default_timezone_set('UTC'); at the top

2. "Class 'ccxt\binance' not found"

  • Solution: Run composer require ccxt/ccxt
  • Check you're using \ccxt\binance with leading backslash

3. "RateLimitExceeded"

  • Solution: Enable rate limiter: 'enableRateLimit' => true

4. "AuthenticationError"

  • Solution: Check API key and secret
  • Verify API key permissions on exchange
  • Check system clock is synced

5. "InvalidNonce"

  • Solution: Sync system clock
  • Use only one exchange instance per API key

6. Missing PHP extensions

  • Solution: Install required extensions:
    • Ubuntu/Debian: apt-get install php-curl php-mbstring php-gmp
    • macOS: Usually pre-installed
    • Windows: Enable in php.ini

Debugging

// Enable verbose logging
$exchange->verbose = true;

// Check exchange capabilities
print_r($exchange->has);
// Array(
//   'fetchTicker' => true,
//   'fetchOrderBook' => true,
//   'createOrder' => true,
//   ...
// )

// Check market information
print_r($exchange->markets['BTC/USDT']);

// Check last request/response
print_r($exchange->last_http_response);
print_r($exchange->last_json_response);

Prediction Markets

CCXT supports prediction-market exchanges (Polymarket, Kalshi, Limitless, Myriad, Hyperliquid) under a dedicated \ccxt\prediction namespace (async-only, ReactPHP โ€” \ccxt\prediction\<id> IS the async class). They use the same unified API, but prices are quoted 0โ€“1 (USDC per outcome share) and the tradeable unit is an outcome (e.g. a market's YES/NO token), not a regular market symbol.

use React\Async;

// async-only (ReactPHP)
$exchange = new \ccxt\prediction\polymarket();
Async\await($exchange->load_markets());
// discover events -> markets -> outcomes
$events = Async\await($exchange->fetch_events(['query' => 'Trump']));
$outcome = $events[0]['markets'][0]['outcomes'][0];
// each outcome has: outcome (handle, e.g. 'TRUMP_OUT_PRESIDENT_2027:YES'),
// outcomeId, market, label ('YES'/'NO')
$handle = $outcome['outcome'];
$ticker = Async\await($exchange->fetch_ticker($handle));
$book = Async\await($exchange->fetch_order_book($handle));
// limit buy 5 YES shares @ 0.40 USDC (price is 0..1 per share)
$order = Async\await($exchange->create_order($handle, 'limit', 'buy', 5, 0.40));
Async\await($exchange->cancel_order($order['id'], $handle));
  • Price/trade methods (fetch_ticker, fetch_order_book, fetch_ohlcv, fetch_trades, create_order, cancel_order, โ€ฆ) take an outcome handle or outcomeId (the outcome / outcomes parameter), not symbol.
  • Check support with $exchange->has['prediction']; discover markets via fetch_events / fetch_event (or load_markets).

Learn More

Frequently asked questions about CCXT for PHP

Similar skills