DEV Community

Cover image for Introducing zoomex-go: A Golang Client for the Zoomex Crypto Exchange API
Igor
Igor

Posted on

Introducing zoomex-go: A Golang Client for the Zoomex Crypto Exchange API

If you're a Go developer building tools for the cryptocurrency derivatives market, you know how much time gets lost dealing with raw HTTP plumbing, HMAC signature generation, and WebSocket connection management before you can even write a single line of business logic. zoomex-go is an open-source library by Igor Sazonov that solves exactly this problem for the Zoomex exchange — providing a clean, idiomatic Go wrapper around the full Zoomex v3 API.

What is Zoomex?

Zoomex is a cryptocurrency derivatives exchange established in 2021, offering over 500 perpetual contracts across both USDT-margined (linear) and coin-margined (inverse) instruments, with leverage up to 150x. It has gained traction among derivatives traders for its broad asset coverage, deep liquidity, and low-friction onboarding. The exchange exposes a well-documented REST and WebSocket API (v3) that allows developers to build trading bots, market data collectors, risk management tools, and portfolio trackers programmatically.

Why a Dedicated Go Client?

Go is a natural fit for high-performance trading infrastructure. Its goroutine-based concurrency model, low latency, and strong standard library make it a popular choice for building exchange connectors, order management systems, and data pipelines. However, writing a robust API client from scratch means dealing with:

  • HMAC-SHA256 request signing with timestamps and receive windows
  • Correct construction of X-BAPI-* authentication headers
  • Parsing and mapping API responses to typed Go structs
  • Managing WebSocket connections, heartbeats, and reconnection logic

zoomex-go handles all of this transparently, so you can start interacting with the exchange in minutes rather than hours.

Installation

The library requires Go 1.21 or later and can be installed with a single command:

go get github.com/tigusigalpa/zoomex-go
Enter fullscreen mode Exit fullscreen mode

Client Configuration

The client is configured using a functional options pattern, which is idiomatic Go and keeps the API clean and extensible:

client := zoomex.NewClient(
    zoomex.WithTestnet(true),             // use testnet (default: mainnet)
    zoomex.WithAPIKey("your-api-key"),    // API key for private endpoints
    zoomex.WithSecretKey("your-secret"), // secret for HMAC signing
    zoomex.WithRecvWindow(10000),         // request validity window in ms
    zoomex.WithHTTPClient(customClient), // bring your own http.Client
)
Enter fullscreen mode Exit fullscreen mode

The same options apply to the WebSocket client. Switching between testnet and mainnet is a single boolean flag — no URL juggling required. The library resolves the correct base URLs automatically:

Environment REST Endpoint WebSocket Endpoint
Mainnet https://openapi.zoomex.com wss://stream.zoomex.com/v3/private
Testnet https://openapi-testnet.zoomex.com wss://stream-testnet.zoomex.com/v3/private

REST API Usage

All REST methods accept a context.Context as their first argument, enabling proper timeout and cancellation handling — a must-have for production trading systems.

Fetching Market Data

tickers, err := client.Market.GetTickers(context.Background(), &zoomex.GetTickersRequest{
    Category: zoomex.CategoryLinear,
    Symbol:   "BTCUSDT",
})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Last price: %s\n", tickers.List[0].LastPrice)
Enter fullscreen mode Exit fullscreen mode

Placing an Order

Private endpoints are authenticated automatically. There is no need to calculate timestamps or build signature strings manually:

order, err := client.Trade.PlaceOrder(ctx, &zoomex.PlaceOrderRequest{
    Category:    zoomex.CategoryLinear,
    Symbol:      "BTCUSDT",
    Side:        zoomex.OrderSideBuy,
    OrderType:   zoomex.OrderTypeLimit,
    Qty:         "0.001",
    Price:       "30000",
    TimeInForce: zoomex.TimeInForceGTC,
    TakeProfit:  "35000",
    StopLoss:    "28000",
})
Enter fullscreen mode Exit fullscreen mode

Managing Positions

// Set leverage
client.Position.SetLeverage(ctx, &zoomex.SetLeverageRequest{
    Category:     zoomex.CategoryLinear,
    Symbol:       "BTCUSDT",
    BuyLeverage:  "10",
    SellLeverage: "10",
})

// Switch to isolated margin
client.Position.SwitchIsolated(ctx, &zoomex.SwitchIsolatedRequest{
    Category:     zoomex.CategoryLinear,
    Symbol:       "BTCUSDT",
    TradeMode:    zoomex.MarginModeIsolated,
    BuyLeverage:  "10",
    SellLeverage: "10",
})
Enter fullscreen mode Exit fullscreen mode

WebSocket API Usage

The WebSocket client uses a callback-based API. Subscriptions are non-blocking — you pass a handler function and the library invokes it on each incoming message:

ws := zoomex.NewWebSocket(
    zoomex.WithAPIKey("your-api-key"),
    zoomex.WithSecretKey("your-secret"),
)
defer ws.Close()

// Public: real-time order book
ws.SubscribeOrderbook("BTCUSDT", func(data *zoomex.OrderbookData) {
    log.Printf("Orderbook: %+v\n", data)
})

// Private: order status updates
ws.SubscribeOrder(func(data *zoomex.OrderUpdateData) {
    log.Printf("Order update: %+v\n", data)
})

// Private: wallet balance changes
ws.SubscribeWallet(func(data *zoomex.WalletUpdateData) {
    log.Printf("Wallet: %+v\n", data)
})

select {} // keep alive
Enter fullscreen mode Exit fullscreen mode

Full API Coverage

The library covers all major service areas of the Zoomex v3 API:

Service Endpoints
Market Server Time, Kline (and Mark/Index/Premium variants), Tickers, Orderbook, Instruments Info, Funding Rate History, Public Trade History, Risk Limit
Trade Place / Amend / Cancel Order, Cancel All Orders, Open Orders, Order History, Trade History
Position Position Info, Set Leverage, Switch Isolated/Cross Margin, Set Trading Stop, Set Risk Limit
Account Wallet Balance, Upgrade Status
Asset Coin Info, All Coins Balance, Single Coin Balance, Internal Transfers, Subaccount Transfers, Deposit Records, Withdrawal Records, Withdraw, Cancel Withdrawal, Coin Exchange History, Delivery/Settlement Records
WebSocket (Public) Orderbook
WebSocket (Private) Order, Position, Execution, Wallet

Error Handling and Best Practices

The library follows standard Go conventions: every method returns a typed result and an error. API-level errors from Zoomex (non-zero retCode) are surfaced as Go errors with the format "API error: code=<retCode>, msg=<retMsg>", making them easy to handle and log.

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

result, err := client.Market.GetTickers(ctx, req)
if err != nil {
    log.Printf("Error: %v", err)
    return
}
Enter fullscreen mode Exit fullscreen mode

A few recommended practices when using the library in production:

  • Store API keys in environment variables, never in source code.
  • Always test new strategies on the testnet first (get testnet keys at testnet.zoomex.com).
  • Use context.WithTimeout to prevent hanging requests.
  • Always call ws.Close() (ideally via defer) to release WebSocket resources cleanly.

Getting Involved

The project is MIT-licensed and open to contributions. If you encounter a missing endpoint, a bug, or want to improve the library, pull requests are welcome on the GitHub repository. The repository also includes an examples/ directory with runnable code samples to help you get started quickly.


Links:

Top comments (0)