Documentation
¶
Overview ¶
Package ctgexchange is a Go client for the CTG.EXCHANGE exchange API.
CTG.EXCHANGE is a hybrid crypto exchange (off-chain matcher, on-chain custody on BNB Smart Chain). This package is a thin, typed client over its public REST + WebSocket API.
c := ctgexchange.NewClient(ctgexchange.Config{APIKey: key, APISecret: secret})
balances, err := c.GetBalances(ctx)
Every monetary value is a decimal string (the API's decimal contract), never a float — parse it with a big-decimal library if you need arithmetic. Withdrawals are intentionally not part of the API.
Index ¶
- Constants
- Variables
- func RESTCanonicalString(ts int64, method, requestURI, body string) string
- func RESTHeaders(keyID, secret, method, requestURI, body string, ts int64) map[string]string
- func SHA256Hex(body string) string
- func SignREST(secret string, ts int64, method, requestURI, body string) string
- func SignWSAuth(secret string, ts int64) string
- func WSAuthMessage(keyID, secret string, ts int64) map[string]any
- type APIError
- type Balance
- type BookLevel
- type Candle
- type CandleOptions
- type Client
- func (c *Client) CancelAllOrders(ctx context.Context, symbol string) ([]Order, error)
- func (c *Client) CancelOrder(ctx context.Context, symbol, orderID string) (Order, error)
- func (c *Client) GetBalances(ctx context.Context) ([]Balance, error)
- func (c *Client) GetCandles(ctx context.Context, symbol, interval string, opts CandleOptions) ([]Candle, error)
- func (c *Client) GetFees(ctx context.Context) (UserFees, error)
- func (c *Client) GetMyTrades(ctx context.Context, symbol string, q TradeQuery) ([]Trade, error)
- func (c *Client) GetOpenOrders(ctx context.Context) ([]Order, error)
- func (c *Client) GetOrder(ctx context.Context, symbol, orderID string) (Order, error)
- func (c *Client) GetOrderBook(ctx context.Context, symbol string) (OrderBook, error)
- func (c *Client) GetOrders(ctx context.Context, symbol string, q OrderQuery) ([]Order, error)
- func (c *Client) GetSymbols(ctx context.Context) ([]Symbol, error)
- func (c *Client) GetTicker(ctx context.Context, symbol string) (Ticker, error)
- func (c *Client) GetTickers(ctx context.Context) ([]Ticker, error)
- func (c *Client) GetTrades(ctx context.Context, symbol string, limit int) ([]Trade, error)
- func (c *Client) ModifyOrder(ctx context.Context, symbol, orderID string, p ModifyOrderParams) (Order, error)
- func (c *Client) PlaceOrder(ctx context.Context, symbol string, p PlaceOrderParams) (OrderResult, error)
- type Config
- type FeeRebate
- type ModifyOrderParams
- type Order
- type OrderBook
- type OrderQuery
- type OrderResult
- type PlaceOrderParams
- type Rebate
- type Stream
- type StreamConfig
- type StreamMessage
- type Symbol
- type Ticker
- type Trade
- type TradeQuery
- type UserFees
Constants ¶
const DefaultBaseURL = "https://api.ctg.exchange"
DefaultBaseURL is the production REST base URL.
const DefaultWSBaseURL = "wss://api.ctg.exchange"
DefaultWSBaseURL is the production WebSocket base URL.
const Version = "0.1.0"
Version is the SDK version.
Variables ¶
var ErrMissingCredentials = errors.New(
"ctgexchange: api key and secret are required for private endpoints")
ErrMissingCredentials is returned when a private endpoint is called without an API key and secret configured.
var ErrStreamClosed = errors.New("ctgexchange: stream closed")
ErrStreamClosed is returned by Stream.Next once the stream has stopped and will deliver no more messages.
Functions ¶
func RESTCanonicalString ¶
RESTCanonicalString builds the four-field canonical string a REST signature covers:
<ts>\n<METHOD>\n<request-uri>\n<hex sha256 of body>
requestURI is the path plus query string exactly as sent on the request line, e.g. /api/v1/me/orders/CTGUSDT?limit=50.
func RESTHeaders ¶
RESTHeaders returns the three signed headers a private REST request must carry. ts is Unix seconds; the server rejects timestamps outside its signature window (default 30s), so keep the local clock in sync.
func SHA256Hex ¶
SHA256Hex returns the hex SHA-256 of a request body. SHA256Hex("") is the hash used for every body-less request.
func SignREST ¶
SignREST returns the lowercase-hex HMAC-SHA256 of the REST canonical string, keyed by the API key secret.
func SignWSAuth ¶
SignWSAuth returns the lowercase-hex HMAC-SHA256 over "ws-auth\n<ts>".
Types ¶
type APIError ¶
type APIError struct {
// StatusCode is the HTTP status of the response.
StatusCode int
// Code is the API's machine-readable "error" field.
Code string
// Message is the API's human-readable "message" field, if any.
Message string
// RequestID is the API's "request_id" — quote it when reporting.
RequestID string
// RetryAfter is the Retry-After header value in seconds on a 429,
// or 0 when the server did not send one.
RetryAfter int
}
APIError is a non-2xx HTTP response from the API. Inspect StatusCode, or use the Is* helpers, to branch on the kind of failure:
var apiErr *ctgexchange.APIError
if errors.As(err, &apiErr) && apiErr.IsRateLimited() {
time.Sleep(time.Duration(apiErr.RetryAfter) * time.Second)
}
func (*APIError) IsBadRequest ¶
IsBadRequest reports whether the request was malformed (400).
func (*APIError) IsForbidden ¶
IsForbidden reports a wrong-scope key or off-allowlist IP (403).
func (*APIError) IsNotFound ¶
IsNotFound reports an unknown symbol or order (404).
func (*APIError) IsRateLimited ¶
IsRateLimited reports a rate-limit response (429); see RetryAfter.
func (*APIError) IsUnauthorized ¶
IsUnauthorized reports a missing/expired/invalid API key (401).
type Balance ¶
type Balance struct {
Asset string `json:"asset"`
Available string `json:"available"`
Reserved string `json:"reserved"`
}
Balance is a per-asset balance.
type Candle ¶
type Candle struct {
Open string `json:"open"`
High string `json:"high"`
Low string `json:"low"`
Close string `json:"close"`
Volume string `json:"volume"`
OpenTime int64 `json:"open_time"`
CloseTime int64 `json:"close_time"`
Trades int `json:"trades"`
}
Candle is a single OHLC candle.
type CandleOptions ¶
CandleOptions are the optional query parameters for GetCandles. Leave a field zero to omit it. Omit From/To for the latest Limit candles; set them (Unix ms) for a historical window [From, To).
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a REST client for the CTG.EXCHANGE API. It is safe for concurrent use.
func (*Client) CancelAllOrders ¶
CancelAllOrders cancels every open order for symbol (trade scope).
func (*Client) CancelOrder ¶
CancelOrder cancels one order (trade scope).
func (*Client) GetBalances ¶
GetBalances returns the API key owner's per-asset balances (read scope).
func (*Client) GetCandles ¶
func (c *Client) GetCandles( ctx context.Context, symbol, interval string, opts CandleOptions, ) ([]Candle, error)
GetCandles returns candles for symbol at interval (1m/5m/15m/1h/4h/1d; defaults to 1m when empty). See CandleOptions for windowed queries.
func (*Client) GetMyTrades ¶
GetMyTrades returns the owner's trade history for symbol (read scope).
func (*Client) GetOpenOrders ¶
GetOpenOrders returns every open order across all symbols (read scope). Each Order carries its own Symbol; decimal fields are converted per that order's scales. For closed-order history use GetOrders per symbol.
func (*Client) GetOrderBook ¶
GetOrderBook returns the current order book for symbol.
func (*Client) GetSymbols ¶
GetSymbols returns all trading symbols with their order filters.
func (*Client) GetTickers ¶
GetTickers returns the 24h ticker for every symbol.
func (*Client) GetTrades ¶
GetTrades returns recent public trade prints for symbol. A limit of 0 uses the server default.
func (*Client) ModifyOrder ¶
func (c *Client) ModifyOrder( ctx context.Context, symbol, orderID string, p ModifyOrderParams, ) (Order, error)
ModifyOrder modifies a resting order's price and quantity (trade scope). The API expects the full new state — set both fields.
func (*Client) PlaceOrder ¶
func (c *Client) PlaceOrder( ctx context.Context, symbol string, p PlaceOrderParams, ) (OrderResult, error)
PlaceOrder places an order (trade scope). A ClientOrderID is generated when p.ClientOrderID is empty, so retries de-dup safely.
type Config ¶
type Config struct {
APIKey string
APISecret string
BaseURL string // default DefaultBaseURL
Timeout time.Duration // default 10s; ignored when HTTPClient is set
MaxRetries int // retry 429s, honouring Retry-After; default 0
HTTPClient *http.Client // optional custom HTTP client
}
Config configures a Client. APIKey and APISecret are required only for the private (/api/v1/me/...) endpoints; public market data works without them.
type FeeRebate ¶
type FeeRebate struct {
AccountID string `json:"account_id"` // referrer wallet address
FractionBps int `json:"fraction_bps"` // share of the fee in bps
}
FeeRebate is the fraction of a charged fee credited to a referrer. An empty object (zero fields) when no rebate applies.
type ModifyOrderParams ¶
ModifyOrderParams are the parameters for modifying an order. Send both fields — the API expects the full new state.
type Order ¶
type Order struct {
ID string `json:"id"`
ClientOrderID string `json:"client_order_id"`
UID string `json:"uid"` // owner wallet address
Symbol string `json:"symbol"`
Side string `json:"side"` // buy / sell
Type string `json:"type"` // limit / market
TimeInForce string `json:"time_in_force"`
Status string `json:"status"`
Price string `json:"price"`
AvgExecutionPrice string `json:"avg_execution_price"`
Qty string `json:"qty"`
FilledQty string `json:"filled_qty"`
RemainingQty string `json:"remaining_qty"`
FeeAmount string `json:"fee_amount"` // decimal string in fee_asset scale
FeeAsset string `json:"fee_asset"`
TakerFeeBps int `json:"taker_fee_bps"` // per-order override; 0 = default
MakerFeeBps int `json:"maker_fee_bps"`
Rebate *FeeRebate `json:"rebate"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
Order is an order as returned by the API.
type OrderBook ¶
type OrderBook struct {
Symbol string `json:"symbol"`
LastUpdateID int64 `json:"last_update_id"`
Bids []BookLevel `json:"bids"`
Asks []BookLevel `json:"asks"`
}
OrderBook is a full order book snapshot.
type OrderQuery ¶
type OrderQuery struct {
Status string // open / partially_filled / filled / canceled
Limit int
Offset int
}
OrderQuery are the optional filters for GetOrders.
type OrderResult ¶
OrderResult is the response to placing or modifying an order: the order plus any fills that happened immediately.
type PlaceOrderParams ¶
type PlaceOrderParams struct {
Side string // buy / sell
Type string // limit / market
Price string
Qty string
ClientOrderID string
}
PlaceOrderParams are the parameters for placing an order. Price and Qty are decimal strings. ClientOrderID is generated when empty.
type Rebate ¶
type Rebate struct {
ReferrerAccount string `json:"referrer_account"`
FractionBps int `json:"fraction_bps"`
}
Rebate is the referral-rebate entry inside a UserFees snapshot.
type Stream ¶
type Stream struct {
// contains filtered or unexported fields
}
Stream is a WebSocket stream. Call Next in a loop to consume messages; it connects on the first call and, unless reconnect is disabled, transparently reconnects and re-subscribes on a drop. A Stream is not safe for concurrent Next calls.
func NewMarketDataStream ¶
func NewMarketDataStream(cfg StreamConfig) *Stream
NewMarketDataStream opens the public market-data stream — channels orderbook / ticker / candles / trades. No authentication.
func NewUserStream ¶
func NewUserStream(apiKey, apiSecret string, cfg StreamConfig) (*Stream, error)
NewUserStream opens the private stream — the caller's orders / trades / balances — authenticated in-band with a signed first frame.
func (*Stream) Close ¶
func (s *Stream) Close()
Close stops the stream and any reconnection. After Close, Next returns ErrStreamClosed.
func (*Stream) Next ¶
func (s *Stream) Next(ctx context.Context) (StreamMessage, error)
Next returns the next message. It blocks until one arrives, ctx is cancelled, or the stream closes (then it returns ErrStreamClosed or the failure that ended the stream).
func (*Stream) Subscribe ¶
Subscribe adds channels (e.g. "orderbook@CTGUSDT"). They are kept across reconnects.
func (*Stream) Unsubscribe ¶
Unsubscribe drops channels.
type StreamConfig ¶
type StreamConfig struct {
BaseURL string // default DefaultWSBaseURL
Channels []string // (re)subscribed on every connect
DisableReconnect bool // turn off auto-reconnect
ReconnectDelay time.Duration // default 2s
}
StreamConfig configures a WebSocket stream.
type StreamMessage ¶
type StreamMessage struct {
Type string // "snapshot" or "update"
Channel string // e.g. "orderbook"
Symbol string // e.g. "CTGUSDT"; empty for private channels
Data json.RawMessage // channel payload — unmarshal as needed
}
StreamMessage is one server WebSocket message: a snapshot or update.
type Symbol ¶
type Symbol struct {
Symbol string `json:"symbol"`
BaseAsset string `json:"base_asset"`
QuoteAsset string `json:"quote_asset"`
PriceScale int `json:"price_scale"`
QtyScale int `json:"qty_scale"`
QuoteAssetScale int `json:"quote_asset_scale"`
TickSize string `json:"tick_size"`
StepSize string `json:"step_size"`
MinPrice string `json:"min_price"`
MaxPrice string `json:"max_price"`
MinQty string `json:"min_qty"`
MaxQty string `json:"max_qty"`
MinNotional string `json:"min_notional"`
}
Symbol is a trading pair plus its order filters.
type Ticker ¶
type Ticker struct {
Symbol string `json:"symbol"`
Price string `json:"price"`
Open string `json:"open"`
High string `json:"high"`
Low string `json:"low"`
Close string `json:"close"`
Volume string `json:"volume"` // base-asset volume
Trades int `json:"trades"`
ChangeBps int `json:"change_bps"`
Ts int64 `json:"ts"` // epoch
}
Ticker is a 24h rolling ticker.
type Trade ¶
type Trade struct {
ID string `json:"id"`
Symbol string `json:"symbol"`
Price string `json:"price"`
Qty string `json:"qty"`
BuyOrderID string `json:"buy_order_id"`
SellOrderID string `json:"sell_order_id"`
BuyUID string `json:"buy_uid"` // buyer wallet address
SellUID string `json:"sell_uid"` // seller wallet address
AggressorSide string `json:"aggressor_side"`
MakerOrderID string `json:"maker_order_id"`
TakerOrderID string `json:"taker_order_id"`
BuyFeeBps int `json:"buy_fee_bps"` // omitted when 0
SellFeeBps int `json:"sell_fee_bps"` // omitted when 0
BuyRebate *FeeRebate `json:"buy_rebate"`
SellRebate *FeeRebate `json:"sell_rebate"`
BuyFeeAmount string `json:"buy_fee_amount"`
BuyFeeAsset string `json:"buy_fee_asset"`
SellFeeAmount string `json:"sell_fee_amount"`
SellFeeAsset string `json:"sell_fee_asset"`
CreatedAt string `json:"created_at"`
}
Trade is a matched trade. Both sides' addresses, order ids and fees are exposed — see "matcher transparency".
type TradeQuery ¶
TradeQuery are the optional filters for GetMyTrades.
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
account
command
Private account access and order placement.
|
Private account access and order placement. |
|
marketdata
command
Public market data — no API key needed.
|
Public market data — no API key needed. |
|
stream
command
Streaming market data and private account updates over WebSocket.
|
Streaming market data and private account updates over WebSocket. |