bitget

package module
v0.20260618.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2026 License: MIT Imports: 2 Imported by: 0

README

go-bitget

A Go SDK for the Bitget exchange, targeting the Unified Trading Account (UTA) — the /api/v3/* REST API and the v3 WebSocket streams.

Supported Bitget API version: 2026-06-18 (tracks the latest UTA changelog).

  • Faithful to the API. Every response struct is reconciled against the live API, not just the docs (the docs are frequently incomplete). Each public endpoint and every testable private endpoint is covered by a test that diffs the real response's JSON keys against the struct.
  • Ergonomic. Functional options (WithAuth, WithProxy, …), a fluent NewXxxService(...).SetFoo(...).Do(ctx) pattern per endpoint, and generics for response decoding.
  • Correct money & time. Prices/quantities are shopspring/decimal.Decimal; millisecond timestamps are time.Time. Bitget's quirk of sending numbers and timestamps as JSON strings (and ""/"0"/"-1" for "not set") is handled transparently.
  • Extensible. The client / request / signing core is product-agnostic, leaving room for a classic-account module alongside uta.

Install

go get github.com/UnipayFI/go-bitget

Requires Go 1.26+.

Quick start

package main

import (
	"context"
	"fmt"

	bitget "github.com/UnipayFI/go-bitget"
	"github.com/UnipayFI/go-bitget/client"
	"github.com/UnipayFI/go-bitget/uta"
	"github.com/shopspring/decimal"
)

func main() {
	ctx := context.Background()

	c := bitget.NewUTAClient(
		client.WithAuth("apiKey", "apiSecret", "passphrase"),
		// client.WithProxy("socks5://127.0.0.1:7890"),
		// client.WithDemoTrading(true),
	)

	// Align the request clock with the server (avoids signature drift).
	_ = c.SyncServerTime(ctx)

	// Public market data (no auth required).
	instruments, _ := c.NewGetInstrumentsService(uta.CategorySpot).
		SetSymbol("BTCUSDT").Do(ctx)
	fmt.Println(instruments[0].Symbol, instruments[0].PricePrecision)

	// Private account data.
	assets, _ := c.NewGetAccountAssetsService().Do(ctx)
	fmt.Println("equity:", assets.AccountEquity)

	// Place a limit order.
	ref, err := c.NewPlaceOrderService(uta.CategorySpot, "BTCUSDT",
		decimal.RequireFromString("0.0001"), uta.SideBuy, uta.OrderTypeLimit).
		SetPrice(decimal.RequireFromString("30000")).
		SetTimeInForce(uta.TimeInForceGTC).
		Do(ctx)
	if err != nil {
		panic(err)
	}
	fmt.Println("orderId:", ref.OrderId)
}

Authentication

Credentials come from the Bitget API-management page (key, secret, passphrase):

c := bitget.NewUTAClient(client.WithAuth(apiKey, apiSecret, passphrase))

Requests are signed with HMAC-SHA256 over timestamp + method + requestPath(+ "?" + query) + body, base64-encoded into the ACCESS-SIGN header. To sign with an RSA key or an external signer instead, pass client.WithSignFn(fn).

Other options: WithProxy (http/https/socks5), WithBaseURL, WithLocale, WithDemoTrading, WithTimeOffset, WithLogger, WithHTTPClient.

Layout

bitget.go        entry point: NewUTAClient, NewUTAWebSocketClient
client/          core REST client, functional options, HMAC signer config, errors, WS client
request/         request builder, signing, Do[T] envelope decode, WebSocket subscribe
common/          constants, the global time.Time + decimal.Decimal JSON codec
pkg/log/         Logger interface
uta/             unified-account endpoints (one Service per endpoint) + WebSocket channels
cmd/bgraw/       dev tool: sign + dump any endpoint's raw response
Endpoint modules (in uta/)
Area Files Examples
Market data market*.go instruments, tickers, orderbook, candles, funding rate, open interest, risk reserve, discount rate, position tier, …
Account account*.go assets, info, settings, leverage, hold mode, fee rate, financial records, transfer, deposit, withdrawal, …
Trade trade_*.go place/modify/cancel order, batch, cancel-symbol, countdown-cancel, order/fill queries
Position position.go current/history positions, ADL rank, max open available
Strategy strategy.go trigger / TPSL plan orders
Copy / Earn / Tax copy.go earn.go tax.go elite copy trading, on-chain elite earn, tax records
Loans crypto_loan.go ins_loan.go crypto-backed loans, institutional loans
Broker / P2P / Sub-account broker.go p2p.go sub_account.go broker sub-accounts, P2P ads/orders, virtual sub-accounts
WebSocket ws_public.go ws_private.go ws_trade.go public: ticker, kline, orderbook, rpi-orderbook, trade, liquidation; private: account, position, order, fill, fast-fill, strategy-order, adl; order entry over WS: place/modify/cancel + batch

WebSocket

ws := bitget.NewUTAWebSocketClient(
	client.WithWebSocketAuth(apiKey, apiSecret, passphrase), // private channels only
)

// Public ticker.
done, _, err := ws.NewSubscribeTickerService(uta.WsInstTypeUSDTFutures, "BTCUSDT").
	Do(ctx, func(p *request.WsPush[[]uta.WsTicker], err error) {
		if err != nil { return }
		fmt.Println(p.Action, p.Data[0].LastPrice)
	})
// ...
close(done) // unsubscribe + close

// Private account (auto login).
ws.NewSubscribeAccountService().Do(ctx, func(p *request.WsPush[[]uta.WsAccount], err error) {
	// p.Data[0].TotalEquity, p.Data[0].Coin, ...
})

Each Do returns (done chan<- struct{}, stop <-chan struct{}, err error): close done to unsubscribe; stop is closed when the reader exits. The client sends Bitget's ping/pong keepalive automatically.

Orders can also be placed over a persistent, logged-in WebSocket connection (a low-latency alternative to the REST trade endpoints):

tc, _ := ws.DialTrade(ctx)       // connect + login
defer tc.Close()
price := decimal.RequireFromString("30000")
ack, err := tc.PlaceOrder(ctx, uta.CategorySpot, uta.WsNewOrder{
	Symbol: "BTCUSDT", Side: uta.SideBuy, OrderType: uta.OrderTypeLimit,
	Qty: decimal.RequireFromString("0.0001"), Price: &price,
})
// tc.ModifyOrder / tc.CancelOrder / tc.BatchPlaceOrders / ...

Decimals and timestamps

All amounts/prices/rates are decimal.Decimal; all millisecond timestamps are time.Time. A custom JSON codec (registered globally in common/json.go) decodes Bitget's string-encoded numbers and timestamps — including the empty / "0" / "-1" "not set" sentinels, which decode to the zero value — so you never deal with raw strings.

Testing

Tests run against the live API and read credentials from the environment; they skip when unset:

export BITGET_API_KEY=...   BITGET_API_SECRET=...   BITGET_PASSPHRASE=...
export BITGET_PROXY=socks5://127.0.0.1:7890   # optional

go test ./uta/ -run TestAccountConfig -v            # one module at a time
BITGET_TEST_WRITE=1 go test ./uta/ -run TestOrder   # live order tests (tiny, reversible)

Every test hits the live API and verifies that the real response's JSON keys are fully covered by the typed struct. A few notes:

  • Run tests per module (-run TestXxx). Bitget rate-limits to ~1–20 req/s; running the whole suite at once can trip HTTP 429.
  • If your API key has an IP whitelist, requests from a non-whitelisted IP return 40018 Invalid IP — make sure your egress IP is whitelisted.
  • Capability-gated reads (broker, copy-trading, P2P, loans) are skipped when the account lacks that capability (the endpoint + signing are still exercised).

State-changing tests (placing orders, changing settings) are gated behind BITGET_TEST_WRITE=1 and use minimal amounts on large-cap symbols. Destructive endpoints (account downgrade, withdrawals, sub-account/broker creation) are implemented but never executed by the suite.

The cmd/bgraw helper signs and dumps any endpoint's raw response, handy for inspecting private payloads:

go run ./cmd/bgraw GET /api/v3/account/info
go run ./cmd/bgraw GET /api/v3/account/financial-records "coin=USDT&limit=5"

License

See LICENSE.

Documentation

Overview

Package bitget is the entry point of the Bitget exchange Go SDK.

Install: go get github.com/UnipayFI/go-bitget Import: import bitget "github.com/UnipayFI/go-bitget"

The SDK targets Bitget's Unified Trading Account (UTA, the /api/v3/* REST API and the v3 WebSocket streams). Authentication uses the HMAC-SHA256 scheme (ACCESS-KEY / ACCESS-SIGN / ACCESS-TIMESTAMP / ACCESS-PASSPHRASE). The core client/request/sign layers are product-agnostic, leaving room for a future classic-account module alongside uta.

Quick start:

c := bitget.NewUTAClient(
	client.WithAuth(apiKey, apiSecret, passphrase),
)
if err := c.SyncServerTime(ctx); err != nil { /* ... */ }
assets, err := c.NewGetAccountAssetsService().Do(ctx)

WebSocket:

ws := bitget.NewUTAWebSocketClient(
	client.WithWebSocketAuth(apiKey, apiSecret, passphrase),
)
done, _, err := ws.NewSubscribeTickerService(uta.WsInstTypeUSDTFutures, "BTCUSDT").
	Do(ctx, func(p *request.WsPush[[]uta.WsTicker], err error) { /* ... */ })

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewUTAClient

func NewUTAClient(options ...client.Options) *uta.UTAClient

NewUTAClient constructs a REST client for the unified-account /api/v3/* endpoints.

func NewUTAWebSocketClient

func NewUTAWebSocketClient(options ...client.WebSocketOptions) *uta.UTAWebSocketClient

NewUTAWebSocketClient constructs a WebSocket client for the unified-account public and private streams.

Types

This section is empty.

Directories

Path Synopsis
cmd
bgraw command
Command bgraw signs and executes a single Bitget UTA REST call and pretty prints the raw response.
Command bgraw signs and executes a single Bitget UTA REST call and pretty prints the raw response.
pkg
log

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL