Skip to content
Finance
Skill

/new-exchange

Scaffold a new CCXT exchange integration in TypeScript, following the certified-exchange template. Walks through describe(), required unified methods, parsers, capability flags, sandbox setup, and static fixtures. Use when adding support for an exchange that does not exist yet

From plugin
ccxt
45k10 skills1 agent

Claude Code

$ npx -y skills add ccxt/ccxt --skill new-exchange --agent claude-code

SKILL.md

new-exchange.SKILL.md
name: new-exchange
description: Scaffold a new CCXT exchange integration in TypeScript, following the certified-exchange template. Walks through describe(), required unified methods, parsers, capability flags, sandbox setup, and static fixtures. Use when adding support for an exchange that does not exist yet under ts/src/.

New Exchange Integration

Scaffold a new exchange in `ts/src/<id>.ts` (REST) and optionally `ts/src/pro/<id>.ts` (WebSocket).

> **Read first:** `wiki/Requirements.md` (mandatory unified methods) and `CONTRIBUTING.md` (transpiler rules). The CCXT root `CLAUDE.md` is the contributor guide.

Inputs

  • `<id>`: lowercase exchange id, no separators (e.g. `mynewex`)
  • `<Name>`: human-readable name (e.g. `My New Exchange`)
  • API docs URL(s)
  • Whether the exchange has a testnet/sandbox

Step 1 — Pick a reference exchange

Don't write from scratch. Copy a similar exchange that's already certified and adapt it.

| Style | Reference | |---|---| | Spot + futures, signed REST | `ts/src/binance.ts`, `ts/src/okx.ts` | | Spot only | `ts/src/kraken.ts`, `ts/src/coinbase.ts` | | Derivatives focus | `ts/src/bybit.ts`, `ts/src/hyperliquid.ts` | | Decentralised / on-chain signing | `ts/src/hyperliquid.ts`, `ts/src/dydx.ts` | | WebSocket reference | `ts/src/pro/binance.ts`, `ts/src/pro/okx.ts` |

Open the reference next to your new file and pattern-match — never invent new conventions.

Step 2 — Create `ts/src/<id>.ts`

Skeleton:

import Exchange from './abstract/<id>.js';
import { /* errors needed */ } from './base/errors.js';
import { Precise } from './base/Precise.js';
import type { /* types needed */ } from './base/types.js';

export default class <id> extends Exchange {
    describe (): any {
        return this.deepExtend (super.describe (), {
            'id': '<id>',
            'name': '<Name>',
            'countries': [ 'XX' ],
            'rateLimit': 1000,        // ms between requests
            'version': 'v1',
            'certified': false,
            'pro': false,             // flip to true when pro/<id>.ts exists
            'has': {
                // start everything false; flip to true as you implement
                'CORS': undefined,
                'spot': true,
                'margin': false,
                'swap': false,
                'future': false,
                'option': false,
                'fetchMarkets': true,
                'fetchCurrencies': true,
                'fetchTicker': true,
                'fetchTickers': false,
                'fetchOrderBook': true,
                'fetchTrades': true,
                'fetchOHLCV': false,
                'fetchBalance': true,
                'createOrder': true,
                'cancelOrder': true,
                'fetchOrder': true,
                'fetchOpenOrders': true,
                'fetchOrders': false,
                'fetchClosedOrders': false,
                'fetchMyTrades': true,
                'fetchDeposits': false,
                'fetchWithdrawals': false,
                'withdraw': false,
            },
            'urls': {
                'logo': 'https://...',
                'api': {
                    'public': 'https://api.<id>.com',
                    'private': 'https://api.<id>.com',
                },
                'test': {                              // OPTIONAL — only if testnet exists
                    'public': 'https://testnet.<id>.com',
                    'private': 'https://testnet.<id>.com',
                },
                'www': 'https://<id>.com',
                'doc': [ 'https://docs.<id>.com' ],
                'fees': 'https://<id>.com/fees',
            },
            'api': {
                'public': {
                    'get': [
                        'symbols',
                        'ticker/{pair}',
                        'orderbook/{pair}',
                    ],
                },
                'private': {
                    'get': [ 'account', 'orders' ],
                    'post': [ 'order' ],
                    'delete': [ 'order/{id}' ],
                },
            },
            'requiredCredentials': {
                'apiKey': true,
                'secret': true,
                // 'password': true,        // for passphrase-based exchanges
                // 'walletAddress': true,   // for on-chain
                // 'privateKey': true,
            },
            'fees': {
                'trading': {
                    'tierBased': false,
                    'percentage': true,
                    'maker': 0.001,
                    'taker': 0.001,
                },
            },
            'precisionMode': /* TICK_SIZE | DECIMAL_PLACES | SIGNIFICANT_DIGITS */,
            'options': {
                // exchange-specific defaults
            },
            'exceptions': {
                'exact': {
                    // 'ERROR_CODE': BadRequest,
                },
                'broad': {
                    // 'invalid signature': AuthenticationError,
                },
            },
        });
    }

    // implement the unified methods you flipped on in `has`
    async fetchMarkets (params = {}): Promise<Market[]> { /* ... */ }
    parseMarket (market: Dict): Market { /* ... */ }
    async fetchTicker (symbol: string, params = {}): Promise<Ticker> { /* ... */ }
    parseTicker (ticker: Dict, market: Market = undefined): Ticker { /* ... */ }
    // ...

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        // build URL, sign request — use this.hmac, this.jwt, this.ecdsa, never external libs
    }

    handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
        // throw the right exception based on response
    }
}

Step 3 — Define implicit API methods

URLs in the `api` block become methods automatically:

  • `'symbols'` → `this.publicGetSymbols(params)`
  • `'ticker/{pa
Read more
@ccxt
Ships withccxt

A crypto trading API with more than 100 exchanges and prediction markets in JavaScript / TypeScript / Python / C# / PHP / Go / Java / Rust.

45k10 skills1 agent
Get the whole plugin

Stars on GitHub

Momentum

stars in total
44.8k
Star history of ccxt/ccxt on GitHub, a chart by star-history.com

Other skills on ccxt.

ccxt-cli

ccxt-cli

CCXT command-line interface (ccxt-cli) for interacting with 100+ cryptocurrency exchanges directly from the terminal — no code…

@ccxt@ccxtInstall Skill
ccxt-csharp

ccxt-csharp

CCXT cryptocurrency exchange library for C# and .NET developers. Covers both REST API (standard) and WebSocket API (real-time).…

@ccxt@ccxtInstall Skill
ccxt-go

ccxt-go

CCXT cryptocurrency exchange library for Go developers. Covers both REST API (standard) and WebSocket API (real-time). Helps…

@ccxt@ccxtInstall Skill
ccxt-java

ccxt-java

CCXT cryptocurrency exchange library for Java developers. Covers both REST API (standard) and WebSocket API (real-time). Helps…

@ccxt@ccxtInstall Skill
ccxt-mcp

ccxt-mcp

Official CCXT MCP (Model Context Protocol) server — connect an AI agent to 100+ cryptocurrency exchanges and prediction markets…

@ccxt@ccxtInstall Skill
ccxt-php

ccxt-php

CCXT cryptocurrency exchange library for PHP developers. Covers both REST API (standard) and WebSocket API (real-time). Helps…

@ccxt@ccxtInstall Skill

More skills from other plugins.

Questions about new-exchange.

Which coding agents can use new-exchange?
new-exchange installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.