Skip to content
Skills Library
Programming · Tool integration

ccxt-java

/ccxt-java

CCXT cryptocurrency exchange library for Java developers. Covers both REST API (standard) and WebSocket API (real-time). Helps install CCXT, connect to exchanges, fetch market data, place orders, stream live tickers/orderbooks, handle authentication, and manage errors in Java projects. Use when working with crypto exchanges in Java applications, trading systems, or financial software. Requires Java 21+.

Author
ccxt ↗
Repository
ccxt ↗
Licence
MIT
Last repository change
25.10.2026

Assessment and security

95/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content30 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
1
Scripts
0
HTML comments
0
URLs in SKILL.md
6
Deprecation

No signals detected. Repository changed on 25.10.2026, without references to retired models or APIs.

Licence

MIT, open: use and modify while retaining author attribution.

What it does and when to use it

CCXT cryptocurrency exchange library for Java developers. Covers both REST API (standard) and WebSocket API (real-time). Helps install CCXT, connect to exchanges, fetch market data, place orders, stream live tickers/orderbooks, handle authentication, and manage errors in Java projects. Use when working with crypto exchanges in Java applications, trading systems, or financial software. Requires Java 21+.

Original author description

CCXT cryptocurrency exchange library for Java developers. Covers both REST API (standard) and WebSocket API (real-time). Helps install CCXT, connect to exchanges, fetch market data, place orders, stream live tickers/orderbooks, handle authentication, and manage errors in Java projects. Use when working with crypto exchanges in Java applications, trading systems, or financial software. Requires Java 21+.

How it works

  1. Installation
  2. Quick Start
  3. Architecture: Typed Subclasses
  4. REST vs WebSocket
  5. Creating Exchange Instance
  6. Common REST Operations
  7. Exchange-Specific (Implicit) API
  8. WebSocket Operations (Real-time)
  9. Sync vs Async
  10. Complete Method Reference
Original SKILL.md headings · 730 lines, 2,795 words
SKILL.md preview
---
name: ccxt-java
description: CCXT cryptocurrency exchange library for Java developers. Covers both REST API (standard) and WebSocket API (real-time). Helps install CCXT, connect to exchanges, fetch market data, place orders, stream live tickers/orderbooks, handle authentication, and manage errors in Java projects. Use when working with crypto exchanges in Java applications, trading systems, or financial software. Requires Java 21+.
---

# CCXT for Java

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

## Installation

### Via Gradle
```groovy
// build.gradle
repositories {
    mavenCentral()
}
dependencies {
    implementation 'io.github.ccxt:ccxt:latest.release'
}
```

### Via Maven
```xml
<dependency>
    <groupId>io.github.ccxt</groupId>
    <artifactId>ccxt</artifactId>
    <version>LATEST</version>
</dependency>
```

### Requirements
- Java 21 or higher (uses virtual threads)

## Quick Start

### REST API
```java
import io.github.ccxt.exchanges.Binance;
import io.github.ccxt.types.Ticker;

Binance exchange = new Binance();
exchange.loadMarkets(false);
Ticker ticker = exchange.fetchTicker("BTC/USDT");
System.out.println(ticker.last);
```

### WebSocket API - Real-time Updates
```java
import io.github.ccxt.exchanges.pro.Binance;

var exchange = new Binance();
exchange.loadMarkets(false);
while (true) {
    Ticker ticker = exchange.watchTicker("BTC/USDT"); // typed sync, blocks for one update
    System.out.println(ticker.last);
}
```

## Architecture: Typed Subclasses

Each exchange has two classes following the Go pattern:
- `BinanceCore` - transpiled untyped class (internal, extends `BinanceApi` extends `Exchange`)
- `Binance` - typed wrapper extending Core with typed overloads (user-facing)

```java
// User-facing typed class (recommended)
Binance exchange = new Binance();
Ticker ticker = exchange.fetchTicker("BTC/USDT");       // returns Ticker
List<Trade> trades = exchange.fetchTrades("BTC/USDT");   // returns List<Trade>

// Exchange-specific implicit API methods are also accessible
Object raw = exchange.publicGetTicker24hr(params).join(); // Binance-specific endpoint

// Properties accessible directly
exchange.apiKey = "...";
exchange.secret = "...";
```

The typed methods use Java method overloading. They coexist safely with untyped methods because Java resolves overloads at compile time: `BinanceCore.java` is compiled without knowledge of `Binance.java`'s typed overloads, so internal calls always bind to untyped varargs.

## REST vs WebSocket

| Feature | REST API | WebSocket API |
|---------|----------|---------------|
| **Use for** | One-time queries, placing orders | Real-time monitoring, live price feeds |
| **Import** | `io.github.ccxt.exchanges.Binance` | `io.github.ccxt.exchanges.pro.Binance` |
| **Methods** | `fetch*` (fetchTicker, fetchOrderBook) | `watch*` (watchTicker, watchOrderBook) |
| **Returns** | Typed objects (Ticker, List\<Trade\>) | `CompletableFuture<Object>` (call `.join()`) |
| **Speed** | Slower (HTTP request/response) | Faster (persistent connection) |
| **Rate limits** | Strict (1-2 req/sec) | More lenient (continuous stream) |
| **Best for** | Trading, account management | Price monitoring, arbitrage detection |

## Creating Exchange Instance

### REST API
```java
import io.github.ccxt.exchanges.Binance;
import java.util.Map;
import java.util.HashMap;

// Public API (no authentication)
Binance exchange = new Binance();

// Private API (with authentication)
Map<String, Object> config = new HashMap<>();
config.put("apiKey", "YOUR_API_KEY");
config.put("secret", "YOUR_SECRET");
Binance exchange = new Binance(config);
```

### WebSocket API
```java
import io.github.ccxt.exchanges.pro.Binance;

// Public WebSocket
var exchange = new Binance();

// Private WebSocket (with authentication)
Map<String, Object> config = new HashMap<>();
config.put("apiKey", "YOUR_API_KEY");
config.put("secret", "YOUR_SECRET");
var exchange = new Binance(config);
```

### Dynamic Instantiation (generic, untyped)
```java
import io.github.ccxt.Exchange;

// Returns Exchange type - no typed methods, but works for any exchange
Exchange exchange = Exchange.dynamicallyCreateInstance("binance", config);
Object ticker = exchange.fetchTicker("BTC/USDT").join(); // untyped, returns CompletableFuture
```

## Common REST Operations

### Loading Markets
```java
// Load all available trading pairs (typed)
Map<String, MarketInterface> markets = exchange.loadMarkets(false);

// Access market information
MarketInterface btcMarket = markets.get("BTC/USDT");
System.out.println(btcMarket.base);    // "BTC"
System.out.println(btcMarket.quote);   // "USDT"
System.out.println(btcMarket.active);  // true
```

### Fetching Ticker
```java
// Single ticker (typed)
Ticker ticker = exchange.fetchTicker("BTC/USDT");
System.out.println(ticker.last);      // Last price
System.out.println(ticker.bid);       // Best bid
System.out.println(ticker.ask);       // Best ask
System.out.println(ticker.baseVolume); // 24h volume

// Async variant
CompletableFuture<Ticker> future = exchange.fetchTickerAsync("BTC/USDT", null);
```

### Fetching Order Book
```java
// Full orderbook (typed)
OrderBook orderbook = exchange.fetchOrderBook("BTC/USDT", null, null);
System.out.println(orderbook.bids.get(0)); // [price, amount]
System.out.println(orderbook.asks.get(0)); // [price, amount]

// Limited depth
OrderBook orderbook = exchange.fetchOrderBook("BTC/USDT", 5L, null);
```

### Fetching Trades
```java
// Recent public trades (typed)
List<Trade> trades = exchange.fetchTrades("BTC/USDT");
for (Trade t : trades) {
    System.out.println(t.datetime + " " + t.side + " " + t.price + " x " + t.amount);
}

// With optional params (pass null to skip)
List<Trade> trades = exchange.fetchTrades("BTC/USDT", null, 20L, null);
```

### Fetching OHLCV (Candlesticks)
```java
List<OHLCV> candles = exchange.fetchOHLCV("BTC/USDT", "1h", null, 10L, null);
for (OHLCV c : candles) {
    System.out.println(c.timestamp + " O:" + c.open + " H:" + c.high + " L:" + c.low + " C:" + c.close);
}
```

### Creating Orders

#### Limit Order
```java
// Buy limit order (typed)
Order order = exchange.createOrder("BTC/USDT", "limit", "buy", 0.01, 50000.0, null);
System.out.println(order.id);

// Sell limit order
Order order = exchange.createOrder("BTC/USDT", "limit", "sell", 0.01, 60000.0, null);
```

#### Market Order
```java
// Buy market order
Order order = exchange.createOrder("BTC/USDT", "market", "buy", 0.01, null, null);

// Sell market order
Order order = exchange.createOrder("BTC/USDT", "market", "sell", 0.01, null, null);
```

### Fetching Balance
```java
Balances balance = exchange.fetchBalance((Map<String, Object>) null);
// Access via the info map
System.out.println(balance);
```

### Fetching Orders
```java
// Open orders
List<Order> openOrders = exchange.fetchOpenOrders("BTC/USDT");

// Closed orders
List<Order> closedOrders = exchange.fetchClosedOrders("BTC/USDT");

// Single order by ID
Order order = exchange.fetchOrder("orderId123", "BTC/USDT", null);
```

### Canceling Orders
```java
// Cancel single order
Order cancelled = exchange.cancelOrder("orderId123", "BTC/USDT", null);

// Cancel all orders for a symbol
List<Order> cancelled = exchange.cancelAllOrders("BTC/USDT", null);
```

## Exchange-Specific (Implicit) API

Each exchange class inherits exchange-specific endpoint methods from its Api class. These return `CompletableFuture<Object>` (untyped):

```java
import io.github.ccxt.exchanges.Binance;

Binance exchange = new Binance();
exchange.loadMarkets(false);

// Binance-specific public endpoints
Map<String, Object> params = new HashMap<>();
params.put("symbol", "BTCUSDT");
Object rawTicker = exchange.publicGetTicker24hr(params).join();

// Binance-specific private endpoints (requires auth)
Object accountInfo = exchange.sapiGetAccountInfo(null).join();

// Access raw exchange info
Object exchangeInfo = exchange.publicGetExchangeInfo(null).join();
```

## WebSocket Operations (Real-time)

WebSocket classes are in `io.github.ccxt.exchanges.pro`. They return `CompletableFuture<Object>`:

### Watching Ticker
```java
import io.github.ccxt.exchanges.pro.Binance;

var exchange = new Binance();
exchange.loadMarkets(false);
while (true) {
    Ticker ticker = exchange.watchTicker("BTC/USDT"); // typed sync, blocks for one update
    System.out.println("Last: " + ticker.last);
}
```

### Watching Order Book
```java
var exchange = new Binance();
exchange.loadMarkets(false);
while (true) {
    OrderBook ob = exchange.watchOrderBook("BTC/USDT");
    System.out.println("Best bid: " + ob.bids.get(0));
}
```

### Watching Trades
```java
var exchange = new Binance();
exchange.loadMarkets(false);
while (true) {
    List<Trade> trades = exchange.watchTrades("BTC/USDT");
    for (Trade t : trades) {
        System.out.println(t.price + " " + t.amount + " " + t.side);
    }
}
```

### Watching Your Orders (Private)
```java
Map<String, Object> config = Map.of("apiKey", "KEY", "secret", "SECRET");
var exchange = new Binance(config);
exchange.loadMarkets(false);
while (true) {
    List<Order> orders = exchange.watchOrders("BTC/USDT");
    System.out.println(orders);
}
```

## Sync vs Async

Java CCXT provides three patterns — and the symmetry applies to both REST `fetch*` and WS `watch*` methods.

### 1. Typed Sync (blocking)
```java
// REST — blocks until one HTTP response
Binance exchange = new Binance();
Ticker ticker = exchange.fetchTicker("BTC/USDT");

// WS — blocks until one streaming update
var wsExchange = new io.github.ccxt.exchanges.pro.Binance();
Ticker tick = wsExchange.watchTicker("BTC/USDT");
```

### 2. Typed Async (non-blocking)
```java
// REST async
CompletableFuture<Ticker> future = exchange.fetchTickerAsync("BTC/USDT", null);
future.thenAccept(ticker -> System.out.println(ticker.last));

// WS async — same shape, returns CompletableFuture<Ticker> that completes on next update
CompletableFuture<Ticker> wsFuture = wsExchange.watchTickerAsync("BTC/USDT", null);
wsFuture.thenAccept(tick -> System.out.println(tick.last));

// Compose multiple watches without blocking the calling thread:
CompletableFuture.allOf(
    wsExchange.watchTickerAsync("BTC/USDT", null),
    wsExchange.watchOrderBookAsync("ETH/USDT", null, null)
).join();
```

Every typed `fetch*` and `watch*` method has a matching `*Async` overload at every supported arity, including zero-arg (where the method allows it). Same return-type symmetry: `Ticker fetchTicker(...)` ↔ `CompletableFuture<Ticker> fetchTickerAsync(...)`; `Tickers watchTickers(...)` ↔ `CompletableFuture<Tickers> watchTickersAsync(...)`.

### 3. Untyped (CompletableFuture\<Object\>)
```java
Exchange exchange = Exchange.dynamicallyCreateInstance("binance", null);
Object result = exchange.fetchTicker("BTC/USDT").join();
```

## Complete Method Reference

### Market Data Methods

#### Tickers & Prices
- `fetchTicker(symbol)` - Fetch ticker for one symbol
- `fetchTickers(symbols, params)` - Fetch multiple tickers
- `fetchBidsAsks(symbols, params)` - Fetch best bid/ask
- `fetchLastPrices(symbols, params)` - Fetch last prices
- `fetchMarkPrice(symbol, params)` - Fetch mark price (derivatives)

#### Order Books
- `fetchOrderBook(symbol, limit, params)` - Fetch order book

#### Trades
- `fetchTrades(symbol, since, limit, params)` - Fetch public trades
- `fetchMyTrades(symbol, since, limit, params)` - Fetch your trades (auth required)

#### OHLCV (Candlesticks)
- `fetchOHLCV(symbol, timeframe, since, limit, params)` - Fetch candlestick data

### Account & Balance
- `fetchBalance(params)` - Fetch account balance (auth required)
- `fetchAccounts(params)` - Fetch sub-accounts
- `fetchLedger(code, since, limit, params)` - Fetch ledger history

### Trading Methods

#### Creating Orders
- `createOrder(symbol, type, side, amount, price, params)` - Create order
- `createOrders(orders, params)` - Create multiple orders
- `editOrder(id, symbol, type, side, amount, price, params)` - Modify order

#### Managing Orders
- `fetchOrder(id, symbol, params)` - Fetch single order
- `fetchOrders(symbol, since, limit, params)` - Fetch all orders
- `fetchOpenOrders(symbol, since, limit, params)` - Fetch open orders
- `fetchClosedOrders(symbol, since, limit, params)` - Fetch closed orders
- `cancelOrder(id, symbol, params)` - Cancel single order
- `cancelAllOrders(symbol, params)` - Cancel all orders

### Derivatives & Futures
- `fetchPosition(symbol, params)` - Fetch single position
- `fetchPositions(symbols, params)` - Fetch all positions
- `fetchFundingRate(symbol, params)` - Current funding rate
- `fetchFundingRateHistory(symbol, since, limit, params)` - Funding rate history
- `setLeverage(leverage, symbol, params)` - Set leverage
- `setMarginMode(marginMode, symbol, params)` - Set margin mode

### Deposits & Withdrawals
- `fetchDepositAddress(code, params)` - Get deposit address
- `withdraw(code, amount, address, tag, params)` - Withdraw funds
- `transfer(code, amount, fromAccount, toAccount, params)` - Internal transfer
- `fetchDeposits(code, since, limit, params)` - Fetch deposit history
- `fetchWithdrawals(code, since, limit, params)` - Fetch withdrawal history

### Fees
- `fetchTradingFee(symbol, params)` - Trading fee for symbol
- `fetchTradingFees(params)` - All trading fees

### WebSocket Methods

All REST methods have WebSocket equivalents with `watch*` prefix:
- `watchTicker(symbol)` - Watch single ticker
- `watchTickers(symbols)` - Watch multiple tickers
- `watchOrderBook(symbol)` - Watch order book updates
- `watchTrades(symbol)` - Watch public trades
- `watchOHLCV(symbol, timeframe)` - Watch candlestick updates
- `watchBalance()` - Watch balance updates (auth required)
- `watchOrders(symbol)` - Watch your order updates (auth required)
- `watchMyTrades(symbol)` - Watch your trade updates (auth required)

### Optional Parameters

Java typed methods use null for optional parameters:

```java
// Full params
List<Trade> trades = exchange.fetchTrades("BTC/USDT", sinceTimestamp, 100L, extraParams);

// Skip optional params with null
List<Trade> trades = exchange.fetchTrades("BTC/USDT", null, 100L, null);

// Convenience overload (required params only)
List<Trade> trades = exchange.fetchTrades("BTC/USDT");
```

## Authentication

### Setting API Keys
```java
Map<String, Object> config = new HashMap<>();
config.put("apiKey", System.getenv("BINANCE_API_KEY"));
config.put("secret", System.getenv("BINANCE_SECRET"));
Binance exchange = new Binance(config);

// Or set after creation
exchange.apiKey = System.getenv("BINANCE_API_KEY");
exchange.secret = System.getenv("BINANCE_SECRET");
```

### Testing Authentication
```java
try {
    Balances balance = exchange.fetchBalance((Map<String, Object>) null);
    System.out.println("Authentication successful!");
} catch (CompletionException e) {
    if (e.getCause() instanceof AuthenticationError) {
        System.out.println("Invalid API credentials");
    }
}
```

## Error Handling

### Exception Hierarchy
```
BaseError
+- NetworkError (recoverable - retry)
|  +- RequestTimeout
|  +- ExchangeNotAvailable
|  +- RateLimitExceeded
|  +- DDoSProtection
+- ExchangeError (non-recoverable - don't retry)
   +- AuthenticationError
   +- InsufficientFunds
   +- InvalidOrder
   +- BadSymbol
   +- NotSupported
```

### Basic Error Handling

Typed sync methods (`fetchTicker`, `createOrder`, `fetchBalance`, etc.) unwrap
`CompletionException` internally and rethrow the underlying typed ccxt error,
so users write idiomatic Java `try`/`catch` with multiple typed `catch` blocks
in **most-specific → least-specific** order — same shape as catching
`ArrayIndexOutOfBoundsException` / `IOException` from the JDK:

```java
import io.github.ccxt.errors.*;
import io.github.ccxt.exchanges.Binance;
import io.github.ccxt.types.Ticker;

Binance exchange = new Binance();
try {
    Ticker ticker = exchange.fetchTicker("BTC/USDT");
} catch (NetworkError e) {
    System.out.println("Network error - retry: " + e.getMessage());
} catch (ExchangeError e) {
    System.out.println("Exchange error - do not retry: " + e.getMessage());
}
```

No `CompletionException` boilerplate, no `.getCause()` unwrap needed.

#### Java pitfalls when catching ccxt errors

1. **You cannot multi-catch a parent and child error together.** Java forbids it:
   ```java
   // ❌ compile error — BaseError is parent of NetworkError
   catch (NetworkError | BaseError e) { ... }

   // ✅ separate clauses, most-specific first
   catch (NetworkError e) { ... }
   catch (BaseError e) { ... }
   ```

2. **Passing `null` to a sync method can be ambiguous** for the 13 zero-required-param methods
   (`fetchBalance`, `fetchOrders`, `fetchMyTrades`, `fetchOpenOrders`, `fetchClosedOrders`,
   `fetchCanceledOrders`, `fetchTime`, `fetchStatus`, `fetchTickers`, `fetchPositions`,
   `fetchAccounts`, `fetchCurrencies`, `fetchMarkets`) plus their `*Ws` siblings. These ship both
   a typed `fetchX(Map<String, Object> params)` and the base `fetchX(Object...)` varargs, so a
   bare `null` matches both:
   ```java
   // ❌ "reference to fetchBalance is ambiguous"
   exchange.fetchBalance(null);

   // ✅ use the typed zero-arg overload (these 13 methods ship one)
   exchange.fetchBalance();

   // ✅ or cast to disambiguate (always works)
   exchange.fetchBalance((Map<String, Object>) null);
   ```
   Same applies to `fetchBalanceAsync(null)` etc. For methods outside the list, the typed
   zero-arg form doesn't exist — pass an explicit argument or use the cast form.

3. **The JVM stays alive after `main()` returns** because of internal HTTP/scheduler threads
   (Netty event loop, virtual-thread executors per WS connection). Call `exchange.close()` to
   release them; as a last resort `System.exit(0)` will force-exit. Avoid `Runtime.addShutdownHook`
   — a shutdown hook runs *during* JVM shutdown, it doesn't trigger one.

### Specific Exception Handling

Multi-catch and ordering work exactly as JDK conventions expect:

```java
try {
    Order order = exchange.createOrder("BTC/USDT", "limit", "buy", 0.01, 50000.0, null);
} catch (InsufficientFunds e) {
    System.out.println("Not enough balance: " + e.getMessage());
} catch (InvalidOrder e) {                                  // covers OrderNotFound, DuplicateOrderId, etc.
    System.out.println("Invalid order params: " + e.getMessage());
} catch (AuthenticationError e) {
    System.out.println("Check your API credentials: " + e.getMessage());
} catch (RateLimitExceeded | DDoSProtection e) {             // multi-catch — same handler for both
    Thread.sleep(30_000);
} catch (NetworkError e) {                                   // any other transient: RequestTimeout, ExchangeNotAvailable
    Thread.sleep(2_000);
} catch (ExchangeError e) {                                  // any other exchange-side error
    System.out.println("Exchange refused: " + e.getMessage());
} catch (BaseError e) {                                      // ccxt catch-all (rare)
    System.out.println("CCXT error: " + e.getMessage());
}
```

Note: each `catch` clause must be for a single class; you cannot multi-catch
`NetworkError | BaseError` because BaseError is a parent of NetworkError.
The order above (most-specific to least-specific) is the JDK convention.

### Async Error Handling

For async methods (`fetchTickerAsync`, `createOrderAsync`, …), the returned
`CompletableFuture` wraps exceptions in `CompletionException`. Use the
`Helpers.unwrap()` helper inside `.exceptionally(...)` to peel the wrapper
and pattern-match the underlying ccxt error:

```java
import io.github.ccxt.Helpers;

exchange.fetchTickerAsync("BTC/USDT")
    .thenAccept(t -> System.out.println(t.last()))
    .exceptionally(throwable -> {
        Throwable cause = Helpers.unwrap(throwable);          // peels CompletionException
        return switch (cause) {                                // pattern-matching switch (Java 21+)
            case RateLimitExceeded e   -> { backoff(); yield null; }
            case NetworkError e        -> { retry(); yield null; }
            case AuthenticationError e -> { refreshCredentials(); yield null; }
            case ExchangeError e       -> { logExchangeError(e); yield null; }
            case BaseError e           -> { logCcxtError(e); yield null; }
            default -> throw new java.util.concurrent.CompletionException(cause);
        };
    });
```

If you'd rather block and use the sync exception style, you can also do
`Helpers.joinUnwrapped(future)` instead of calling `.join()` directly — that's
the same helper the typed sync wrappers use internally.

## Rate Limiting

### Built-in Rate Limiter (Enabled by Default)
```java
// Rate limiting is enabled by default
Binance exchange = new Binance();
System.out.println(exchange.enableRateLimit); // true
System.out.println(exchange.rateLimit);       // milliseconds between requests
```

## Proxy Configuration

```java
// 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";
```

## Common Pitfalls

### Typed vs Untyped Methods
```java
// Typed (recommended) - use concrete exchange class
Binance exchange = new Binance();
Ticker ticker = exchange.fetchTicker("BTC/USDT");  // returns Ticker

// Untyped - generic Exchange reference
Exchange exchange = Exchange.dynamicallyCreateInstance("binance", null);
Object result = exchange.fetchTicker("BTC/USDT").join();  // returns Object
```

### Null for Optional Parameters
```java
// Wrong - ambiguous with varargs
exchange.fetchBalance(null);

// Correct - cast null to specific type
exchange.fetchBalance((Map<String, Object>) null);
```

### Wrong Symbol Format
```java
// Wrong
"BTCUSDT"    // No separator
"BTC-USDT"   // Dash separator
"btc/usdt"   // Lowercase

// Correct
"BTC/USDT"   // Unified CCXT format
```

### REST for Real-time Monitoring
```java
// Wrong - wastes rate limits
while (true) {
    Ticker ticker = exchange.fetchTicker("BTC/USDT");
    Thread.sleep(1000);
}

// Correct - use WebSocket
var wsExchange = new io.github.ccxt.exchanges.pro.Binance();
wsExchange.loadMarkets(false);
while (true) {
    Ticker ticker = wsExchange.watchTicker("BTC/USDT"); // typed sync
}
```

## Troubleshooting

### Common Issues

**1. "Java 21 required"**
- Solution: CCXT Java requires Java 21+ for virtual threads

**2. "RateLimitExceeded"**
- Solution: Rate limiting is enabled by default. If you disabled it, re-enable with `exchange.enableRateLimit = true`

**3. "AuthenticationError"**
- Solution: Check API key and secret
- Verify API key permissions on exchange
- Check system clock is synced

**4. "NotSupported"**
- Solution: Check `exchange.has` map for method availability before calling

**5. Typed methods not visible**
- Solution: Use the concrete exchange type (`Binance exchange = new Binance()`) not the generic `Exchange` type

### Debugging
```java
// Enable verbose logging
exchange.verbose = true;

// Check exchange capabilities
System.out.println(exchange.has);
```

## Prediction Markets

CCXT supports prediction-market exchanges (Polymarket, Kalshi, Limitless, Myriad, Hyperliquid) under the `io.github.ccxt.exchanges.prediction` package. 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.

```java
import io.github.ccxt.exchanges.prediction.Polymarket;
import io.github.ccxt.types.PredictionOrder;

Polymarket exchange = new Polymarket();
exchange.loadMarkets();
// discover events -> markets -> outcomes (each outcome has: outcome (handle),
// outcomeId, market, label); fetchEvents / fetchEvent are available too
// an outcome handle looks like 'TRUMP_OUT_PRESIDENT_2027:YES'
String handle = "TRUMP_OUT_PRESIDENT_2027:YES";
var ticker = exchange.fetchTicker(handle);
var book = exchange.fetchOrderBook(handle);
// limit buy 5 YES shares @ 0.40 USDC (price is 0..1 per share)
PredictionOrder order = exchange.createOrder(handle, "limit", "buy", 5.0, 0.40);
exchange.cancelOrder(order.id, handle);
```

- Price/trade methods (`fetchTicker`, `fetchOrderBook`, `fetchOHLCV`, `fetchTrades`, `createOrder`, `cancelOrder`, …) take an **outcome handle or outcomeId** (the `outcome` parameter), not a market symbol.
- Discover markets via `fetchEvents` / `fetchEvent` (or `loadMarkets`).

## Learn More

- [CCXT Manual](https://docs.ccxt.com/)
- [CCXT Pro Documentation](https://docs.ccxt.com/en/latest/ccxt.pro.html)
- [Supported Exchanges](https://github.com/ccxt/ccxt#supported-cryptocurrency-exchange-markets)
- [GitHub Repository](https://github.com/ccxt/ccxt)

Versions

The database has no other skills named ccxt-java.

Database snapshot: 13.11.2026 · package version 13a6db1a72ed (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 91ccxt-go
    CCXT cryptocurrency exchange library for Go developers. Covers both REST API (standard) and WebSocket API (real-time). Helps install CCXT, connect to exchanges, fetch market data, place orders, stream live tickers/orderbooks, handle authentication, and manage errors in Go…
  • 91ccxt-csharp
    CCXT cryptocurrency exchange library for C# and .NET developers. Covers both REST API (standard) and WebSocket API (real-time). Helps install CCXT, connect to exchanges, fetch market data, place orders, stream live tickers/orderbooks, handle authentication, and manage errors in…
  • 100crypto-exchange-integration
    Use when integrating with cryptocurrency exchanges via CCXT, handling WebSocket market data, managing rate limits, implementing order management, or handling Binance/Kraken/IBKR-specific API quirks and reconnection patterns
  • 96java
    Guidelines for building Java base applications Triggers on: **/*.java
  • 100rest-assured
    REST Assured Java library for testing REST APIs. Covers HTTP requests, JSON/XML validation, and Spring Boot integration. USE WHEN: user mentions "rest assured", "api test java", "rest api test", asks about "given when then", "RestAssured", "HTTP test", "JSON validation" DO NOT…
  • 100azure-messaging-webpubsub-java
    Build real-time web applications with Azure Web PubSub SDK for Java. Use when implementing WebSocket-based messaging, live updates, chat applications, or server-to-client push notifications.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.