Skip to content
Development
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
44k10 skills1 agent
Install
$ npx -y skills add ccxt/ccxt --skill new-exchange --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/new-exchange

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

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/bitmex.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/{pair}'`
Read more
Ships withccxt

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

Get the whole plugin
Stats
43,975
Stars
8,833
Forks
Active
Maintenance
Rust
Language
MIT
License
2d ago
Last commit
9y ago
Created

Repo: ccxt/ccxt

Other skills on ccxt.

ccxt-cli
Skill

ccxt-cli

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

@ccxt@ccxtView Skill
ccxt-mcp
Skill

ccxt-mcp

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

@ccxt@ccxtView Skill