Package Exports
- @ygcc/ygcc
- @ygcc/ygcc/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@ygcc/ygcc) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
YGCC — Cryptocurrency Exchange Library
Lightweight, unified REST & WebSocket API for cryptocurrency exchanges. One interface, 42 exchanges.
Overview
YGCC is a JavaScript library for cryptocurrency trading that provides a unified API across multiple exchanges. Write your trading logic once — it works on every supported exchange without modification.
Built from 5+ years of production trading experience across 40+ exchanges.
Features
- Unified API — Same method signatures across all exchanges (
fetchTicker,createOrder,watchOrderBook, etc.) - REST + WebSocket — Full market data, trading, and real-time streaming support
- Weight-Aware Rate Limiting — Token-bucket limiter that syncs with exchange response headers
- Auto-Reconnect WebSocket — Exponential backoff with jitter, automatic resubscription
- Typed Error Hierarchy —
AuthenticationError,InsufficientFunds,RateLimitExceeded, etc. - Minimal Dependencies — Only
wsfor WebSocket support - HMAC-SHA256 Authentication — Secure request signing with timestamp synchronization
- Testnet Support — Built-in sandbox mode for safe testing
Supported Exchanges
CEX (Centralized)
| # | Exchange | ID | REST | WebSocket | Status |
|---|---|---|---|---|---|
| 1 | Binance | binance |
✅ | ✅ | Ready |
| 2 | Bybit | bybit |
✅ | ✅ | Ready |
| 3 | OKX | okx |
🔜 | 🔜 | Planned |
| 4 | Coinbase | coinbase |
🔜 | 🔜 | Planned |
| 5 | KuCoin | kucoin |
🔜 | 🔜 | Planned |
| 6 | Gate.io | gateio |
🔜 | 🔜 | Planned |
| 7 | Bitfinex | bitfinex |
🔜 | 🔜 | Planned |
| 8 | Bitstamp | bitstamp |
🔜 | 🔜 | Planned |
| 9 | Gemini | gemini |
🔜 | 🔜 | Planned |
| 10 | Crypto.com | cryptocom |
🔜 | 🔜 | Planned |
| 11 | Bittrex | bittrex |
🔜 | 🔜 | Planned |
| 12 | Bitrue | bitrue |
🔜 | 🔜 | Planned |
| 13 | LBANK | lbank |
🔜 | 🔜 | Planned |
| 14 | BitMart | bitmart |
🔜 | 🔜 | Planned |
| 15 | Bitforex | bitforex |
🔜 | 🔜 | Planned |
| 16 | Phemex | phemex |
🔜 | 🔜 | Planned |
| 17 | Pionex | pionex |
🔜 | 🔜 | Planned |
| 18 | Bibox | bibox |
🔜 | 🔜 | Planned |
| 19 | Bitexen | bitexen |
🔜 | 🔜 | Planned |
| 20 | VALR | valr |
🔜 | 🔜 | Planned |
| 21 | WhiteBit | whitebit |
🔜 | 🔜 | Planned |
| 22 | BtcTurk | btcturk |
🔜 | 🔜 | Planned |
| 23 | BTSE | btse |
🔜 | 🔜 | Planned |
| 24 | EXMO | exmo |
🔜 | 🔜 | Planned |
| 25 | CoinTR | cointr |
🔜 | 🔜 | Planned |
| 26 | Coinzix | coinzix |
🔜 | 🔜 | Planned |
| 27 | DigiFinex | digifinex |
🔜 | 🔜 | Planned |
| 28 | HotCoin | hotcoin |
🔜 | 🔜 | Planned |
| 29 | iCrypex | icrypex |
🔜 | 🔜 | Planned |
| 30 | JBEX | jbex |
🔜 | 🔜 | Planned |
| 31 | Kuna | kuna |
🔜 | 🔜 | Planned |
| 32 | Narkasa | narkasa |
🔜 | 🔜 | Planned |
| 33 | NovaDax | novadax |
🔜 | 🔜 | Planned |
| 34 | PointPay | pointpay |
🔜 | 🔜 | Planned |
| 35 | QMall | qmall |
🔜 | 🔜 | Planned |
| 36 | TruBit | trubit |
🔜 | 🔜 | Planned |
| 37 | TradeOgre | tradeogre |
🔜 | 🔜 | Planned |
| 38 | TIDEX | tidex |
🔜 | 🔜 | Planned |
| 39 | Latoken | latoken |
🔜 | 🔜 | Planned |
| 40 | Polymarket | polymarket |
🔜 | 🔜 | Planned |
DEX (Decentralized)
| # | Exchange | ID | REST | WebSocket | Status |
|---|---|---|---|---|---|
| 41 | Hyperliquid | hyperliquid |
🔜 | 🔜 | Planned |
| 42 | ZKLighter | zklighter |
🔜 | 🔜 | Planned |
✅ = Implemented 🔜 = Coming Soon
Installation
npm install ygccOr clone directly:
git clone https://github.com/yuzgecoguz/ygcc.git
cd ygcc
npm installQuick Start
Fetch Market Data (Public — No API Key Needed)
const { Binance } = require('ygcc');
const exchange = new Binance();
(async () => {
// Load all trading pairs
await exchange.loadMarkets();
console.log(`${exchange.symbols.length} symbols loaded`);
// Get BTC price
const ticker = await exchange.fetchTicker('BTCUSDT');
console.log(`BTC: $${ticker.last} (${ticker.percentage}%)`);
// Order book (top 5 levels)
const book = await exchange.fetchOrderBook('BTCUSDT', 5);
console.log(`Best bid: $${book.bids[0][0]} | Best ask: $${book.asks[0][0]}`);
// OHLCV candlesticks
const candles = await exchange.fetchOHLCV('BTCUSDT', '1h', undefined, 5);
console.log(`Last 5 hourly candles:`, candles);
})();Place Orders (Private — API Key Required)
const { Binance } = require('ygcc');
const exchange = new Binance({
apiKey: process.env.BINANCE_API_KEY,
secret: process.env.BINANCE_SECRET,
enableRateLimit: true,
});
(async () => {
// Check balance
const balance = await exchange.fetchBalance();
console.log('USDT:', balance.USDT);
// Place a limit order
const order = await exchange.createLimitOrder('BTCUSDT', 'BUY', 0.001, 50000);
console.log(`Order ${order.id}: ${order.status}`);
// Cancel it
const canceled = await exchange.cancelOrder(order.id, 'BTCUSDT');
console.log(`Canceled: ${canceled.status}`);
})();WebSocket Streaming (Real-Time)
const { Binance } = require('ygcc');
const exchange = new Binance();
// Real-time ticker updates
exchange.watchTicker('BTCUSDT', (ticker) => {
console.log(`BTC: $${ticker.last} | Bid: $${ticker.bid} | Ask: $${ticker.ask}`);
});
// Real-time trades
exchange.watchTrades('ETHUSDT', (trade) => {
console.log(`${trade.side.toUpperCase()} ${trade.amount} ETH @ $${trade.price}`);
});
// Real-time order book
exchange.watchOrderBook('BTCUSDT', (book) => {
const spread = book.asks[0][0] - book.bids[0][0];
console.log(`Spread: $${spread.toFixed(2)}`);
}, 5);
// Graceful shutdown
process.on('SIGINT', async () => {
await exchange.closeAllWs();
process.exit(0);
});Using Bybit
const { Bybit } = require('ygcc');
const exchange = new Bybit();
(async () => {
await exchange.loadMarkets();
console.log(`${exchange.symbols.length} symbols loaded`);
const ticker = await exchange.fetchTicker('BTCUSDT');
console.log(`BTC: $${ticker.last}`);
const book = await exchange.fetchOrderBook('BTCUSDT', 50);
console.log(`Best bid: $${book.bids[0][0]} | Best ask: $${book.asks[0][0]}`);
})();Bybit Trading (Private)
const { Bybit } = require('ygcc');
const exchange = new Bybit({
apiKey: process.env.BYBIT_API_KEY,
secret: process.env.BYBIT_SECRET,
});
(async () => {
const balance = await exchange.fetchBalance();
console.log('USDT:', balance.USDT);
// Bybit V5 uses POST for orders (not query string like Binance)
const order = await exchange.createLimitOrder('BTCUSDT', 'Buy', 0.001, 50000);
console.log(`Order ${order.id}: ${order.status}`);
// Cancel uses POST too (not DELETE like Binance)
const canceled = await exchange.cancelOrder(order.id, 'BTCUSDT');
console.log(`Canceled: ${canceled.status}`);
})();Testnet / Sandbox Mode
// Binance testnet
const binance = new Binance({
apiKey: 'testnet-key',
secret: 'testnet-secret',
options: { sandbox: true }, // Uses testnet.binance.vision
});
// Bybit testnet
const bybit = new Bybit({
apiKey: 'testnet-key',
secret: 'testnet-secret',
options: { sandbox: true }, // Uses api-testnet.bybit.com
});Unified API Reference
All exchanges implement the same method signatures:
Market Data (Public)
| Method | Description | Binance | Bybit |
|---|---|---|---|
loadMarkets() |
Load trading pairs, filters, precision rules | ✅ | ✅ |
fetchTicker(symbol) |
24hr price statistics | ✅ | ✅ |
fetchTickers(symbols?) |
All tickers at once | ✅ | ✅ |
fetchOrderBook(symbol, limit?) |
Bids & asks depth | ✅ | ✅ |
fetchTrades(symbol, since?, limit?) |
Recent public trades | ✅ | ✅ |
fetchOHLCV(symbol, timeframe?, since?, limit?) |
Candlestick / kline data | ✅ | ✅ |
fetchAvgPrice(symbol) |
Current average price | ✅ | |
fetchPrice(symbol?) |
Quick price lookup (lightweight) | ✅ | |
fetchBookTicker(symbol?) |
Best bid/ask only | ✅ | |
fetchTime() |
Server time | ✅ |
Trading (Private — Signed)
| Method | Description | Binance | Bybit |
|---|---|---|---|
createOrder(symbol, type, side, amount, price?, params?) |
Place any order type | ✅ | ✅ |
createLimitOrder(symbol, side, amount, price) |
Limit order shortcut | ✅ | ✅ |
createMarketOrder(symbol, side, amount) |
Market order shortcut | ✅ | ✅ |
cancelOrder(id, symbol) |
Cancel single order | ✅ | ✅ |
cancelAllOrders(symbol) |
Cancel all open orders | ✅ | ✅ |
amendOrder(id, symbol, params) |
Modify existing order | ✅ | ✅ |
createOCO(symbol, side, qty, price, stopPrice) |
One-Cancels-Other | ✅ | |
createOTO(...) |
One-Triggers-Other | ✅ | |
createOTOCO(...) |
One-Triggers-OCO | ✅ | |
testOrder(...) |
Validate without placing | ✅ |
Account (Private — Signed)
| Method | Description | Binance | Bybit |
|---|---|---|---|
fetchBalance() |
Account balances (free, used, total) | ✅ | ✅ |
fetchOrder(id, symbol) |
Single order status | ✅ | ✅ |
fetchOpenOrders(symbol?) |
All open orders | ✅ | ✅ |
fetchClosedOrders(symbol, ...) |
Closed order history | ✅ | ✅ |
fetchMyTrades(symbol, ...) |
Trade history with fees | ✅ | ✅ |
fetchTradingFees(symbol) |
Maker/taker fee rates | ✅ | |
fetchCommission(symbol) |
Maker/taker commission rates | ✅ |
WebSocket Streams
| Method | Description | Binance | Bybit |
|---|---|---|---|
watchTicker(symbol, callback) |
Real-time ticker | ✅ | ✅ |
watchAllTickers(callback) |
All tickers stream | ✅ | |
watchOrderBook(symbol, callback, levels?) |
Real-time order book | ✅ | ✅ |
watchTrades(symbol, callback) |
Real-time trades | ✅ | ✅ |
watchKlines(symbol, interval, callback) |
Real-time candlesticks | ✅ | ✅ |
watchBookTicker(symbol, callback) |
Real-time best bid/ask | ✅ | |
watchBalance(callback) |
Balance updates (private) | ✅ | ✅ |
watchOrders(callback) |
Order updates (private) | ✅ | ✅ |
Unified Response Formats
Ticker
{
symbol: 'BTCUSDT',
last: 97500.00,
bid: 97499.50, bidVolume: 1.5,
ask: 97500.50, askVolume: 0.8,
high: 98200.00, low: 96800.00,
open: 97000.00, close: 97500.00,
volume: 12345.678,
quoteVolume: 1204567890.12,
change: 500.00,
percentage: 0.515,
timestamp: 1700000000000,
datetime: '2023-11-14T22:13:20.000Z',
}Order Book
{
symbol: 'BTCUSDT',
bids: [[97500.00, 1.5], [97499.00, 2.0], ...], // [price, quantity]
asks: [[97501.00, 0.8], [97502.00, 1.2], ...],
timestamp: 1700000000000,
nonce: 123456789,
}Order
{
id: '12345678',
clientOrderId: 'myOrder1',
symbol: 'BTCUSDT',
type: 'LIMIT',
side: 'BUY',
price: 95000.00,
amount: 0.01,
filled: 0.005,
remaining: 0.005,
cost: 475.00,
average: 95000.00,
status: 'PARTIALLY_FILLED', // NEW, FILLED, CANCELED, EXPIRED, REJECTED
timestamp: 1700000000000,
trades: [{ price, amount, commission, commissionAsset }],
}Balance
{
BTC: { free: 0.50, used: 0.10, total: 0.60 },
USDT: { free: 5000, used: 1000, total: 6000 },
timestamp: 1700000000000,
}Error Handling
YGCC provides typed errors for precise error handling:
const {
Binance,
AuthenticationError,
InsufficientFunds,
RateLimitExceeded,
InvalidOrder,
OrderNotFound,
BadSymbol,
NetworkError,
} = require('ygcc');
try {
await exchange.createOrder('BTCUSDT', 'LIMIT', 'BUY', 0.001, 95000);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Check your API key and secret');
} else if (error instanceof InsufficientFunds) {
console.error('Not enough balance');
} else if (error instanceof RateLimitExceeded) {
console.error('Slow down — rate limited');
} else if (error instanceof InvalidOrder) {
console.error('Order rejected:', error.message);
} else if (error instanceof NetworkError) {
console.error('Connection issue — retry');
}
}Error Hierarchy
Error
└── ExchangeError
├── AuthenticationError // Invalid API key, signature, or timestamp
├── RateLimitExceeded // 429 / 418 responses
├── InsufficientFunds // Not enough balance
├── InvalidOrder // Filter violations, bad params
├── OrderNotFound // Order doesn't exist
├── BadSymbol // Invalid trading pair
├── BadRequest // Malformed request
├── ExchangeNotAvailable // Exchange maintenance
└── NetworkError
└── RequestTimeout // Request exceeded timeoutRate Limiting
YGCC automatically tracks and respects exchange rate limits:
const exchange = new Binance({ enableRateLimit: true }); // Default: true
// Monitor rate limit usage
exchange.on('rateLimitWarning', ({ used, limit }) => {
console.warn(`Rate limit: ${used}/${limit} weight used`);
});Binance uses a weight-based system (6000 weight/minute). Each endpoint has a different weight cost. YGCC tracks the X-MBX-USED-WEIGHT-1M response header and automatically throttles requests when approaching the limit.
Architecture
ygcc/
├── index.js # Entry point: const { Binance, Bybit } = require('ygcc')
├── lib/
│ ├── BaseExchange.js # Abstract base class — unified interface
│ ├── binance.js # Binance implementation (1369 lines, 59 methods)
│ ├── bybit.js # Bybit V5 implementation (1021 lines, 45 methods)
│ └── utils/
│ ├── crypto.js # HMAC-SHA256 signing
│ ├── errors.js # Typed error classes
│ ├── helpers.js # Safe value extraction, query builders
│ ├── throttler.js # Token-bucket rate limiter
│ └── ws.js # WebSocket with auto-reconnect
├── examples/
│ ├── fetch-ticker.js # Public market data demo
│ ├── place-order.js # Trading demo
│ └── websocket-stream.js # Real-time streaming demo
└── tests/
├── binance.test.js # 82 tests — Binance implementation
└── bybit.test.js # Bybit V5 implementation testsAdding a New Exchange
Every exchange extends BaseExchange and implements:
const BaseExchange = require('./BaseExchange');
class MyExchange extends BaseExchange {
describe() {
return {
id: 'myexchange',
name: 'My Exchange',
version: 'v1',
rateLimit: 100,
urls: { api: 'https://api.myexchange.com' },
has: { fetchTicker: true, createOrder: true, ... },
};
}
_sign(path, method, params) {
// Exchange-specific authentication
}
async loadMarkets() { /* ... */ }
async fetchTicker(symbol) { /* ... */ }
async createOrder(symbol, type, side, amount, price) { /* ... */ }
// ... implement all supported methods
}Tests
npm test▶ Module Exports (4 tests)
▶ Binance Constructor (7 tests)
▶ BaseExchange (1 test)
▶ Binance Authentication (5 tests)
▶ Binance Parsers (8 tests)
▶ Binance Error Mapping (9 tests)
▶ Binance Rate Limit Header Handling (2 tests)
▶ Binance API Methods — mocked (16 tests)
▶ Utility Functions (18 tests)
▶ Crypto Utilities (4 tests)
▶ Throttler (5 tests)
▶ Error Classes (4 tests)
▶ Binance market() lookup (3 tests)
▶ Module Exports — Bybit (3 tests)
▶ Bybit Constructor (10 tests)
▶ Bybit Authentication (6 tests)
▶ Bybit Response Unwrapping (4 tests)
▶ Bybit Parsers (10 tests)
▶ Bybit Helper Methods (3 tests)
▶ Bybit Error Mapping (13 tests)
▶ Bybit HTTP Error Handling (5 tests)
▶ Bybit Rate Limit Header Handling (3 tests)
▶ Bybit API Methods — mocked (20 tests)
▶ Bybit market() lookup (3 tests)
▶ Bybit vs Binance Differences (5 tests)
165 passing — 243msRoadmap
- Binance Spot — Full REST + WebSocket (59 methods)
- Bybit V5 — Full REST + WebSocket (45 methods)
- OKX — REST + WebSocket
- Gate.io — Spot + Futures
- KuCoin — REST + WebSocket
- Futures/Margin support (Binance USDM, COINM)
- TypeScript type definitions
- npm publish
Related Projects
- crypto-exchange-connector-library — Production connector framework for 50+ exchanges (2025)
- crypto-triangular-arbitrage-engine — 30-40ms triangular arbitrage engine (2022)
- funding-rate-arbitrage-scanner — Delta-neutral funding rate strategy (2025)
- ethereum-smart-contract-security-audit — Smart contract vulnerability detection benchmark (2025)
- oracle-manipulation-attack-demo — Flash loan oracle manipulation PoC (2025)
License
MIT License - see LICENSE for details.
Author
Oguzhan Yuzgec — Blockchain Security & Quant Developer
- GitHub: @yuzgecoguz
- LinkedIn: oguzhan-yuzgec