A modern C++ SDK for interacting with the Coinbase Advanced API, providing both REST and WebSocket functionality for trading, market data, and account management.
- REST API Support: Complete implementation of Coinbase Advanced API endpoints for accounts, orders, products, trades, and more
- WebSocket Support: Real-time market data streaming with level2, ticker, market trades, and user data channels
- Connection lifecycle callbacks for connect/disconnect events
- Per-client sequence number tracking for multiple concurrent connections
- Explicit shutdown control with
stop()method
- Comprehensive Order Types: Support for market, limit, stop limit, bracket, and TWAP orders
- Type Safety: Full C++ type definitions for all API responses with JSON serialization/deserialization
- Modern C++: Uses C++20 features, RAII, smart pointers, and modern C++ best practices
- Async/Await Support: Built-in async support using C++ coroutines
- Thread-Safe: Designed for multi-threaded applications with lock-free data structures
The SDK is organized into several key components:
include/coinbase/
├── account.h # Account and balance management
├── auth.h # Authentication utilities
├── candle.h # Candlestick data
├── common.h # Common types and enums
├── fill.h # Fill data
├── market_data.h # Market data structures
├── order.h # Order management
├── position.h # Position management
├── price_book.h # Price book data
├── product.h # Product information
├── rest.h # REST client implementation
├── rest_awaitable.h # Async REST operations
├── side.h # Order side definitions
├── trades.h # Trade data
├── utils.h # Utility functions
└── websocket.h # WebSocket client implementation
- C++20 compatible compiler (GCC 10+, Clang 10+, MSVC 2019+)
- CMake 3.20+
- OpenSSL
- nlohmann/json (JSON library)
- jwt-cpp (JSON Web Token library)
- slick-net (networking library - automatically fetched via CMake)
- vcpkg (optional, dependency management)
mkdir build
cd build
cmake ..
cmake --build .This repo includes a vcpkg.json manifest. If you use vcpkg, dependencies are installed automatically via the toolchain file. If a vcpkg port for slick-net is available, it will be used; otherwise CMake falls back to FetchContent.
cmake -S . -B build \
-DCMAKE_TOOLCHAIN_FILE=C:/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build#include <coinbase/rest.h>
// Create client
coinbase::CoinbaseRestClient client;
// Get server time
auto timestamp = client.get_server_time();
// List accounts
auto accounts = client.list_accounts();
// Get product information
auto product = client.get_product("BTC-USD");
// Create order
auto response = client.create_order(
"client_order_id_123",
"BTC-USD",
coinbase::Side::BUY,
coinbase::OrderType::LIMIT,
coinbase::TimeInForce::GOOD_UNTIL_CANCELLED,
0.001,
50000.0,
true // post_only
);
// Cancel order
auto cancel_response = client.cancel_orders({"order_id_123"});The SDK provides two callback mechanisms for handling WebSocket data:
-
WebsocketCallbacks: Callbacks are invoked directly on the WebSocket thread. Use this for simple applications or when you want immediate processing. -
UserThreadWebsocketCallbacks: Callbacks are invoked on your own thread. The WebSocket data is queued in a lock-free queue, and you control when to process it by callingprocessData(). Use this for better control over threading and to avoid blocking the WebSocket thread.
#include <coinbase/websocket.h>
class MyCallbacks : public coinbase::WebsocketCallbacks {
public:
// Connection lifecycle callbacks
void onMarketDataConnected(coinbase::WebSocketClient* client) override {
// Handle market data connection established
}
void onMarketDataDisconnected(coinbase::WebSocketClient* client) override {
// Handle market data disconnection
}
void onUserDataConnected(coinbase::WebSocketClient* client) override {
// Handle user data connection established
}
void onUserDataDisconnected(coinbase::WebSocketClient* client) override {
// Handle user data disconnection
}
// Data callbacks
void onLevel2Snapshot(coinbase::WebSocketClient* client, uint64_t seq_num,
const coinbase::Level2UpdateBatch& snapshot) override {
// Handle level2 snapshot
}
void onLevel2Updates(coinbase::WebSocketClient* client, uint64_t seq_num,
const coinbase::Level2UpdateBatch& updates) override {
// Handle level2 updates
}
void onMarketTrades(coinbase::WebSocketClient* client, uint64_t seq_num,
const std::vector<coinbase::MarketTrade>& trades) override {
// Handle market trades
}
// Error callbacks
void onMarketDataError(coinbase::WebSocketClient* client, std::string&& err) override {
// Handle market data errors
}
void onUserDataError(coinbase::WebSocketClient* client, std::string&& err) override {
// Handle user data errors
}
// ... other callback methods
};
// Create WebSocket client
MyCallbacks callbacks;
coinbase::WebSocketClient client(&callbacks);
// Subscribe to channels
std::vector<std::string> product_ids = {"BTC-USD", "ETH-USD"};
std::vector<coinbase::WebSocketChannel> channels = {
coinbase::WebSocketChannel::LEVEL2,
coinbase::WebSocketChannel::TICKER
};
client.subscribe(product_ids, channels);
// Explicitly stop WebSocket connections when done
client.stop();#include <coinbase/websocket.h>
class MyCallbacks : public coinbase::UserThreadWebsocketCallbacks {
public:
// Same callback signatures as WebsocketCallbacks
void onMarketDataConnected(coinbase::WebSocketClient* client) override {
// Handle market data connection established
}
void onLevel2Snapshot(coinbase::WebSocketClient* client, uint64_t seq_num,
const coinbase::Level2UpdateBatch& snapshot) override {
// Handle level2 snapshot
}
// ... other callback methods
};
// Create callbacks and WebSocket client
MyCallbacks callbacks;
coinbase::WebSocketClient client(&callbacks);
// Subscribe to channels
client.subscribe({"BTC-USD", "ETH-USD"}, {
coinbase::WebSocketChannel::LEVEL2,
coinbase::WebSocketChannel::TICKER
});
// In your main loop or dedicated thread, process queued data
while (running) {
// Process up to 100 queued messages per call
callbacks.processData(100);
// Your other application logic here
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
client.stop();Key Differences:
WebsocketCallbacks: Immediate processing on WebSocket I/O thread. Simple but can block WebSocket operations if callbacks are slow.UserThreadWebsocketCallbacks: Deferred processing on your thread. Better performance and control, but requires callingprocessData()regularly. Uses lock-free queues for efficient data transfer between threads.
- Accounts: List accounts, get account details
- Products: List products, get product details
- Orders: Create, list, get, modify, and cancel orders
- Fills: List fills
- Market Data: Get best bid/ask, price book, market trades, candles
- Time: Get server time
- Level2: Order book updates
- Ticker: Price updates
- Market Trades: Trade updates
- User: User-specific data (orders, positions)
- Candles: Candlestick data
- Status: Product status updates
The SDK supports multiple order types:
- Market Orders: Execute immediately at market price
- Limit Orders: Execute at specified price
- Stop Limit Orders: Execute when stop price is hit, then as limit order
- Bracket Orders: Place both stop loss and take profit orders
- TWAP Orders: Split order execution over time
The SDK handles JWT authentication automatically using the coinbase::generate_coinbase_jwt function. You need to provide your API key and secret.
The SDK includes comprehensive unit tests using Google Test. To run tests:
cd build
cmake -DBUILD_COINBASE_ADVANCED_TESTS=ON ..
cmake --build .
cd tests
./coinbase_advance_testsMIT License - see LICENSE file for details.
Contributions are welcome! Please submit a pull request with your changes.
For issues and questions, please open an issue on the GitHub repository.