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
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
)
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)
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",
})
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",
})
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
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
}
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.WithTimeoutto prevent hanging requests. - Always call
ws.Close()(ideally viadefer) 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:
- GitHub: https://github.com/tigusigalpa/zoomex-go
- Zoomex API v3 Docs: https://zoomexglobal.github.io/docs/v3/intro
- Zoomex Exchange: https://www.zoomex.com
Top comments (0)