exchanges

package module
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2026 License: MIT Imports: 12 Imported by: 0

README

exchanges

English | 中文

A unified Go SDK for interacting with multiple cryptocurrency exchanges.

Provides both low-level SDK clients (REST + WebSocket) and high-level adapters implementing a common Exchange interface — a Go-native CCXT alternative.

Features

  • Unified Interface — One API to rule them all. Switch exchanges by changing one line.
  • Full Market Coverage — Perpetual Futures, Spot, and Margin trading support.
  • Dual Transport — REST for queries; WebSocket for real-time streaming and low-latency order placement.
  • Built-in Safety — Declarative rate limiting, automatic IP ban detection/recovery, order validation, and slippage protection.
  • Local State Management — WebSocket-maintained orderbooks, position/order tracking, and balance sync.
  • Production-Ready — Battle-tested in quantitative trading systems handling thousands of orders daily.

Supported Exchanges

Exchange Perp Spot Margin Quote Currencies Default
Binance USDT, USDC USDT
OKX USDT, USDC USDT
Aster USDT, USDC USDC
Nado USDT USDT
Lighter USDC USDC
Hyperliquid USDC USDC
StandX DUSD DUSD
GRVT USDT USDT
EdgeX USDC USDC

Installation

go get github.com/QuantProcessing/exchanges

Design Philosophy

1. Adapter Pattern

Every exchange implements the same Exchange interface. Your strategy code never touches exchange-specific APIs:

// This function works with ANY exchange — Binance, OKX, Hyperliquid, etc.
func getSpread(ctx context.Context, adp exchanges.Exchange, symbol string) (decimal.Decimal, error) {
    ob, err := adp.FetchOrderBook(ctx, symbol, 1)
    if err != nil {
        return decimal.Zero, err
    }
    return ob.Asks[0].Price.Sub(ob.Bids[0].Price), nil
}
2. Symbol Convention

All methods accept a base currency symbol (e.g. "BTC", "ETH"). The adapter handles conversion to exchange-specific formats internally based on the configured quote currency:

You Pass Binance (USDT) Binance (USDC) OKX (USDT) Hyperliquid
"BTC" "BTCUSDT" "BTCUSDC" "BTC-USDT-SWAP" "BTC"
3. Two-Layer Architecture
┌─────────────────────────────────────────────────────┐
│  Your Strategy / Application                        │
├─────────────────────────────────────────────────────┤
│  Adapter Layer (exchanges.Exchange interface)        │  ← Unified API
│    binance.Adapter / okx.Adapter / nado.Adapter     │
├─────────────────────────────────────────────────────┤
│  SDK Layer (low-level REST + WebSocket clients)      │  ← Exchange-specific
│    binance/sdk/ / okx/sdk/ / nado/sdk/              │
└─────────────────────────────────────────────────────┘
  • Adapter Layer: Implements exchanges.Exchange. Handles symbol mapping, order validation, slippage logic, rate limiting, and state management.
  • SDK Layer: Thin REST/WebSocket clients that map 1:1 to exchange API endpoints. You can use these directly for maximum flexibility.

Quick Start

Basic Usage
package main

import (
    "context"
    "fmt"

    exchanges "github.com/QuantProcessing/exchanges"
    "github.com/QuantProcessing/exchanges/binance"
    "github.com/shopspring/decimal"
)

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

    // Create a Binance perpetual adapter (defaults to USDT market)
    adp, err := binance.NewAdapter(ctx, binance.Options{
        APIKey:    "your-api-key",
        SecretKey: "your-secret-key",
        // QuoteCurrency: exchanges.QuoteCurrencyUSDC, // uncomment for USDC market
    })
    if err != nil {
        panic(err)
    }
    defer adp.Close()

    // Fetch ticker
    ticker, err := adp.FetchTicker(ctx, "BTC")
    if err != nil {
        panic(err)
    }
    fmt.Printf("BTC price: %s\n", ticker.LastPrice)

    // Fetch order book
    ob, err := adp.FetchOrderBook(ctx, "BTC", 5)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Best bid: %s, Best ask: %s\n",
        ob.Bids[0].Price, ob.Asks[0].Price)

    // Place a limit order
    order, err := adp.PlaceOrder(ctx, &exchanges.OrderParams{
        Symbol:   "BTC",
        Side:     exchanges.OrderSideBuy,
        Type:     exchanges.OrderTypeLimit,
        Price:    ticker.Bid,
        Quantity: decimal.NewFromFloat(0.001),
    })
    if err != nil {
        panic(err)
    }
    fmt.Printf("Order placed: %s\n", order.OrderID)
}
Market Order with Slippage Protection
// Market order with 0.5% slippage protection
// Internally converts to LIMIT IOC at (ask * 1.005) for buys
order, err := adp.PlaceOrder(ctx, &exchanges.OrderParams{
    Symbol:   "ETH",
    Side:     exchanges.OrderSideBuy,
    Type:     exchanges.OrderTypeMarket,
    Quantity: decimal.NewFromFloat(0.1),
    Slippage: decimal.NewFromFloat(0.005), // 0.5%
})
Convenience Functions
// One-liner market order
order, err := exchanges.PlaceMarketOrder(ctx, adp, "BTC", exchanges.OrderSideBuy, qty)

// One-liner limit order
order, err := exchanges.PlaceLimitOrder(ctx, adp, "BTC", exchanges.OrderSideBuy, price, qty)

// Market order with slippage
order, err := exchanges.PlaceMarketOrderWithSlippage(ctx, adp, "BTC", exchanges.OrderSideBuy, qty, slippage)
WebSocket Streaming
// Real-time order book (locally maintained)
err := adp.WatchOrderBook(ctx, "BTC", func(ob *exchanges.OrderBook) {
    fmt.Printf("BTC bid: %s ask: %s\n", ob.Bids[0].Price, ob.Asks[0].Price)
})

// Pull latest snapshot anytime (zero-latency, no API call)
ob := adp.GetLocalOrderBook("BTC", 5)

// Real-time ticker
adp.WatchTicker(ctx, "BTC", func(t *exchanges.Ticker) {
    fmt.Printf("Price: %s\n", t.LastPrice)
})

// Real-time order updates (fills, cancellations)
adp.WatchOrders(ctx, func(o *exchanges.Order) {
    fmt.Printf("Order %s: %s\n", o.OrderID, o.Status)
})

// Real-time position updates
adp.WatchPositions(ctx, func(p *exchanges.Position) {
    fmt.Printf("%s: %s %s @ %s\n", p.Symbol, p.Side, p.Quantity, p.EntryPrice)
})
Using PerpExchange Extensions
// Type assert for perp-specific features
if perp, ok := adp.(exchanges.PerpExchange); ok {
    // Set leverage
    perp.SetLeverage(ctx, "BTC", 10)

    // Get positions
    positions, _ := perp.FetchPositions(ctx)
    for _, p := range positions {
        fmt.Printf("%s: %s %s\n", p.Symbol, p.Side, p.Quantity)
    }

    // Get funding rate
    fr, _ := perp.FetchFundingRate(ctx, "BTC")
    fmt.Printf("Funding rate: %s\n", fr.FundingRate)
}
AccountManager (Auto-Sync State)
// AccountManager subscribes to WS updates and keeps local state in sync
mgr, err := exchanges.NewAccountManager(adp.(exchanges.PerpExchange), nil)
if err != nil {
    panic(err)
}
err = mgr.Start(ctx, 1*time.Minute) // REST refresh every minute as backup

// Read state anytime (thread-safe, zero-latency)
pos, ok := mgr.GetPosition("BTC")
order, ok := mgr.GetOrder("order-123")
balance := mgr.GetLocalBalance()

// Stream updates via channels
go func() {
    for order := range mgr.GetOrderStream() {
        fmt.Printf("Order update: %s %s\n", order.OrderID, order.Status)
    }
}()
Switching Exchanges
// Binance — USDT market (default)
adp, _ := binance.NewAdapter(ctx, binance.Options{
    APIKey: os.Getenv("BINANCE_API_KEY"), SecretKey: os.Getenv("BINANCE_SECRET"),
})

// Binance — USDC market
adpUSDC, _ := binance.NewAdapter(ctx, binance.Options{
    APIKey: os.Getenv("BINANCE_API_KEY"), SecretKey: os.Getenv("BINANCE_SECRET"),
    QuoteCurrency: exchanges.QuoteCurrencyUSDC,
})

// OKX — same interface, different constructor
adp, _ := okx.NewAdapter(ctx, okx.Options{
    APIKey: os.Getenv("OKX_API_KEY"), SecretKey: os.Getenv("OKX_SECRET"),
    Passphrase: os.Getenv("OKX_PASSPHRASE"),
})

// Hyperliquid — wallet-based auth (USDC only)
adp, _ := hyperliquid.NewAdapter(ctx, hyperliquid.Options{
    PrivateKey: os.Getenv("HL_PRIVATE_KEY"), AccountAddr: os.Getenv("HL_ADDR"),
})

// All adapters expose the exact same Exchange interface
ticker, _ := adp.FetchTicker(ctx, "BTC")
Quote Currency

Each adapter supports a QuoteCurrency option that determines which quote currency market to connect to. If omitted, the exchange-specific default is used (CEX → USDT, DEX → USDC).

// Available quote currencies
exchanges.QuoteCurrencyUSDT // "USDT"
exchanges.QuoteCurrencyUSDC // "USDC"
exchanges.QuoteCurrencyDUSD // "DUSD" (StandX only)

Passing an unsupported quote currency returns an error at construction time:

// This will fail: Hyperliquid only supports USDC
_, err := hyperliquid.NewAdapter(ctx, hyperliquid.Options{
    QuoteCurrency: exchanges.QuoteCurrencyUSDT, // error!
})
// err: "hyperliquid: unsupported quote currency "USDT", supported: [USDC]"

API Reference

Exchange Interface (Core)

Every adapter implements these methods:

Category Method Description
Identity GetExchange() Returns exchange name (e.g. "BINANCE")
GetMarketType() Returns "perp" or "spot"
Close() Closes all connections
Symbol FormatSymbol(symbol) Converts "BTC" → exchange format
ExtractSymbol(symbol) Converts exchange format → "BTC"
ListSymbols() Returns all available symbols
Market Data FetchTicker(ctx, symbol) Latest price, bid/ask, 24h volume
FetchOrderBook(ctx, symbol, limit) Order book snapshot (REST)
FetchTrades(ctx, symbol, limit) Recent trades
FetchKlines(ctx, symbol, interval, opts) Candlestick/OHLCV data
Trading PlaceOrder(ctx, params) Place order (market/limit/post-only)
CancelOrder(ctx, orderID, symbol) Cancel a single order
CancelAllOrders(ctx, symbol) Cancel all open orders for a symbol
FetchOrder(ctx, orderID, symbol) Get order status
FetchOpenOrders(ctx, symbol) List all open orders
Account FetchAccount(ctx) Full account: balance + positions + orders
FetchBalance(ctx) Available balance only
FetchSymbolDetails(ctx, symbol) Precision & min quantity rules
FetchFeeRate(ctx, symbol) Maker/taker fee rates
Orderbook WatchOrderBook(ctx, symbol, cb) Subscribe to WS orderbook (blocks until ready)
GetLocalOrderBook(symbol, depth) Read local WS-maintained orderbook
StopWatchOrderBook(ctx, symbol) Unsubscribe
Streaming WatchOrders(ctx, cb) Real-time order updates
WatchPositions(ctx, cb) Real-time position updates
WatchTicker(ctx, symbol, cb) Real-time ticker
WatchTrades(ctx, symbol, cb) Real-time trades
WatchKlines(ctx, symbol, interval, cb) Real-time klines
PerpExchange Interface (extends Exchange)
Method Description
FetchPositions(ctx) Get all open positions
SetLeverage(ctx, symbol, leverage) Set leverage for a symbol
FetchFundingRate(ctx, symbol) Current funding rate
FetchAllFundingRates(ctx) All funding rates
ModifyOrder(ctx, orderID, symbol, params) Modify an open order (price/qty)
SpotExchange Interface (extends Exchange)
Method Description
FetchSpotBalances(ctx) Per-asset balances (free/locked)
TransferAsset(ctx, params) Transfer between spot/futures accounts
OrderParams
type OrderParams struct {
    Symbol      string          // Base symbol: "BTC", "ETH"
    Side        OrderSide       // OrderSideBuy or OrderSideSell
    Type        OrderType       // OrderTypeMarket, OrderTypeLimit, OrderTypePostOnly
    Quantity    decimal.Decimal // Order quantity
    Price       decimal.Decimal // Required for LIMIT orders
    TimeInForce TimeInForce     // GTC (default), IOC, FOK
    ReduceOnly  bool            // Reduce-only order
    Slippage    decimal.Decimal // If > 0, MARKET → LIMIT IOC with slippage
    ClientID    string          // Client-defined order ID
}
Error Handling
order, err := adp.PlaceOrder(ctx, params)
if err != nil {
    // Structured error matching
    if errors.Is(err, exchanges.ErrInsufficientBalance) {
        // Handle insufficient balance
    }
    if errors.Is(err, exchanges.ErrMinQuantity) {
        // Handle below minimum quantity
    }
    if errors.Is(err, exchanges.ErrRateLimited) {
        // Handle rate limit (auto-handled by built-in limiter)
    }

    // Access exchange-specific details
    var exErr *exchanges.ExchangeError
    if errors.As(err, &exErr) {
        fmt.Printf("[%s] Code: %s, Message: %s\n", exErr.Exchange, exErr.Code, exErr.Message)
    }
}

Available sentinel errors: ErrInsufficientBalance, ErrRateLimited, ErrInvalidPrecision, ErrOrderNotFound, ErrSymbolNotFound, ErrMinNotional, ErrMinQuantity, ErrAuthFailed, ErrNetworkTimeout, ErrNotSupported.


Built-in Safety Features

Rate Limiting

Each adapter comes with exchange-specific rate limiters pre-configured. The sliding-window rate limiter supports:

  • Multiple time windows (e.g., 1200 req/min + 10 req/sec)
  • Category-based weights (different endpoints consume different quotas)
  • Automatic blocking until quota is available
IP Ban Detection & Recovery

If an exchange returns a ban error (HTTP 418/429 with retry-after), the adapter:

  1. Automatically parses the ban duration
  2. Blocks all subsequent requests until the ban expires
  3. Resumes normal operation — no manual intervention needed
Order Validation

Before sending orders, adapters automatically:

  • Round price to symbol's price precision
  • Truncate quantity to symbol's quantity precision
  • Validate minimum quantity and notional constraints

Logger

All adapters accept an optional Logger for structured logging:

// Compatible with *zap.SugaredLogger
logger := zap.NewProduction().Sugar()
adp, _ := binance.NewAdapter(ctx, binance.Options{
    APIKey: "...", SecretKey: "...",
    Logger: logger,
})

If no logger is provided, NopLogger is used. The interface:

type Logger interface {
    Debugw(msg string, keysAndValues ...any)
    Infow(msg string, keysAndValues ...any)
    Warnw(msg string, keysAndValues ...any)
    Errorw(msg string, keysAndValues ...any)
}

Project Structure

exchanges/                  Root package — interfaces, models, errors, utilities
├── exchange.go             Core Exchange / PerpExchange / SpotExchange interfaces
├── models.go               Unified data types (Order, Position, Ticker, etc.)
├── errors.go               Sentinel errors + ExchangeError type
├── base_adapter.go         Shared adapter logic (rate limit, ban, orderbook, validation)
├── local_state.go          LocalOrderBook interface + AccountManager
├── log.go                  Logger interface + NopLogger
├── ratelimit/              Declarative sliding-window rate limiter
├── testsuite/              Adapter compliance test suite
├── binance/                Binance adapter + SDK
│   ├── options.go          Options{APIKey, SecretKey, QuoteCurrency, Logger}
│   ├── perp_adapter.go     Perp adapter (Exchange + PerpExchange)
│   ├── spot_adapter.go     Spot adapter (Exchange + SpotExchange)
│   └── sdk/                Low-level REST & WebSocket clients
├── okx/                    OKX (same structure)
├── aster/                  Aster
├── nado/                   Nado
├── lighter/                Lighter
├── hyperliquid/            Hyperliquid
├── standx/                 StandX
├── grvt/                   GRVT (build tag: grvt)
└── edgex/                  EdgeX (build tag: edgex)

Testing

Copy the example environment file and fill in your credentials:

cp .env.example .env

Run unit tests (no API keys needed):

go test ./ratelimit/ -v
go test . -run TestBan -v
go test -run "Test(Options|Format|Extract)" ./binance/ ./okx/ ./aster/ ./grvt/ -v  # QuoteCurrency tests

Run integration tests (requires API keys in .env):

go test ./binance/ -v      # Tests skip automatically if keys are missing
go test ./grvt/ -v
go test ./edgex/ -v

License

MIT

Documentation

Overview

Package exchanges provides a unified Go SDK for interacting with multiple cryptocurrency exchanges. It offers both low-level SDK clients (REST + WebSocket) and high-level adapters implementing a common Exchange interface.

Quick Start

adp, err := binance.NewAdapter(ctx, binance.Options{
    APIKey:    "your-api-key",
    SecretKey: "your-secret-key",
})
if err != nil {
    log.Fatal(err)
}
defer adp.Close()

ticker, err := adp.FetchTicker(ctx, "BTC")

Architecture

The package is organized into several layers:

  • Root package (exchanges): Unified interfaces, models, errors, and utilities
  • Exchange packages (binance/, okx/, ...): Exchange-specific adapters and SDK clients
  • Ratelimit package: Declarative sliding-window rate limiter
  • Testsuite package: Adapter compliance test suite

Logger

All adapters accept an optional Logger interface for structured logging. The interface is compatible with *zap.SugaredLogger. If no logger is provided, NopLogger is used (all output discarded).

Symbol Convention

All Exchange methods accept a base currency symbol (e.g. "BTC", "ETH"). The adapter handles conversion to exchange-specific formats internally.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInsufficientBalance = errors.New("insufficient balance")
	ErrRateLimited         = errors.New("rate limited")
	ErrInvalidPrecision    = errors.New("invalid precision")
	ErrOrderNotFound       = errors.New("order not found")
	ErrSymbolNotFound      = errors.New("symbol not found")
	ErrMinNotional         = errors.New("below minimum notional")
	ErrMinQuantity         = errors.New("below minimum quantity")
	ErrAuthFailed          = errors.New("authentication failed")
	ErrNetworkTimeout      = errors.New("network timeout")
	ErrNotSupported        = errors.New("not supported")
)

Functions

func CountDecimalPlaces

func CountDecimalPlaces(s string) int32

CountDecimalPlaces returns how many significant decimal places a string representation has. Trailing zeros are not counted: "0.00010" → 4, "0.10" → 1.

func DerivePartialFillStatus added in v0.1.3

func DerivePartialFillStatus(order *Order)

DerivePartialFillStatus adjusts order status to PARTIALLY_FILLED when the exchange reports status as NEW but FilledQuantity > 0. Exchanges like Binance, OKX, and Lighter natively report PARTIALLY_FILLED; this helper is for exchanges that don't (Hyperliquid, Nado, StandX, GRVT, EdgeX).

func FloorToPrecision

func FloorToPrecision(value decimal.Decimal, precision int32) decimal.Decimal

FloorToPrecision truncates (floors) a decimal value to the given number of decimal places.

func FormatDecimal

func FormatDecimal(d decimal.Decimal) string

FormatDecimal formats a decimal to string, stripping trailing zeros.

func GenerateID

func GenerateID() string

GenerateID returns a unique numeric string safe for concurrent use. Values stay within [1, 2^48-1] range required by Lighter; other exchanges accept any numeric string.

func Register

func Register(name string, ctor AdapterConstructor)

Register adds an exchange adapter constructor to the global registry. Call this from each exchange adapter's init() function:

func init() {
    exchanges.Register("BINANCE", func(ctx context.Context, mt exchanges.MarketType, opts map[string]string) (exchanges.Exchange, error) {
        return NewPerpAdapter(ctx, Options{
            APIKey:    opts["api_key"],
            SecretKey: opts["secret_key"],
        })
    })
}

func RegisteredExchanges

func RegisteredExchanges() []string

RegisteredExchanges returns the names of all registered exchanges.

func RoundToPrecision

func RoundToPrecision(value decimal.Decimal, precision int32) decimal.Decimal

RoundToPrecision rounds a decimal value to the given number of decimal places.

func RoundToSignificantFigures

func RoundToSignificantFigures(value decimal.Decimal, sigFigs int32) decimal.Decimal

RoundToSignificantFigures rounds a decimal to n significant figures.

func ValidateAndFormatParams

func ValidateAndFormatParams(params *OrderParams, details *SymbolDetails) error

ValidateAndFormatParams validates and formats order parameters using cached symbol details. It rounds price and truncates quantity to the correct precision.

Types

type Account

type Account struct {
	TotalBalance     decimal.Decimal `json:"total_balance"`
	AvailableBalance decimal.Decimal `json:"available_balance"`
	Positions        []Position      `json:"positions"`
	Orders           []Order         `json:"orders"` // Open orders
	UnrealizedPnL    decimal.Decimal `json:"unrealized_pnl"`
	RealizedPnL      decimal.Decimal `json:"realized_pnl"`
}

Account represents a trading account summary.

type AccountManager

type AccountManager struct {
	// contains filtered or unexported fields
}

AccountManager automates local state management for a perp adapter. It synchronizes Positions, Orders, and Balance via WebSocket and exposes read-only channels. It requires the adapter to implement both PerpExchange and Streamable.

func NewAccountManager

func NewAccountManager(adapter PerpExchange, logger Logger) (*AccountManager, error)

NewAccountManager creates a new manager for the given perp adapter. The adapter must implement both PerpExchange and Streamable.

func (*AccountManager) Close

func (m *AccountManager) Close()

Close closes the manager.

func (*AccountManager) ForceRefresh

func (m *AccountManager) ForceRefresh(ctx context.Context) error

ForceRefresh manually re-fetches full state from REST API.

func (*AccountManager) GetAllPositions

func (m *AccountManager) GetAllPositions() []*Position

GetAllPositions returns a copy of all current positions.

func (*AccountManager) GetLocalBalance

func (m *AccountManager) GetLocalBalance() decimal.Decimal

GetLocalBalance returns the last known balance.

func (*AccountManager) GetOrder

func (m *AccountManager) GetOrder(orderID string) (*Order, bool)

GetOrder returns a copy of the order if found.

func (*AccountManager) GetOrderStream

func (m *AccountManager) GetOrderStream() <-chan *Order

GetOrderStream returns the read-only channel for order updates.

func (*AccountManager) GetPosition

func (m *AccountManager) GetPosition(symbol string) (*Position, bool)

GetPosition returns a copy of the position for the symbol.

func (*AccountManager) GetPositionStream

func (m *AccountManager) GetPositionStream() <-chan *Position

GetPositionStream returns the read-only channel for position updates.

func (*AccountManager) Start

func (m *AccountManager) Start(ctx context.Context, syncInterval time.Duration) error

Start initializes the account state and subscribes to updates.

type AccountType

type AccountType string

AccountType represents an account type for asset transfers.

const (
	AccountTypeSpot    AccountType = "SPOT"    // Spot account
	AccountTypePerp    AccountType = "PERP"    // Perpetual futures account
	AccountTypeUnified AccountType = "UNIFIED" // Unified account
)

type AdapterConstructor

type AdapterConstructor func(ctx context.Context, marketType MarketType, opts map[string]string) (Exchange, error)

AdapterConstructor is the function signature that each exchange registers. It receives an options map and creates an adapter for the requested market type.

func LookupConstructor

func LookupConstructor(name string) (AdapterConstructor, error)

LookupConstructor finds a registered constructor by name.

type BanState

type BanState struct {
	// contains filtered or unexported fields
}

BanState tracks IP ban status using an atomic timestamp for lock-free access. Zero means not banned; non-zero is the unix-ms expiry time.

func (*BanState) BannedFor

func (b *BanState) BannedFor() time.Duration

BannedFor returns the remaining ban duration. Returns 0 if not banned.

func (*BanState) IsBanned

func (b *BanState) IsBanned() (bool, time.Time)

IsBanned returns the current ban status and expiry time. Returns (false, zero) if not banned or ban has expired.

func (*BanState) ParseAndSetBan

func (b *BanState) ParseAndSetBan(err error) bool

ParseAndSetBan checks if an error contains a "banned until" message. If found, records the ban and returns true.

func (*BanState) SetBan

func (b *BanState) SetBan(untilMs int64)

SetBan records a ban that expires at the given unix-ms timestamp.

type BaseAdapter

type BaseAdapter struct {
	*LocalStateManager // Embed state manager for Orders/Positions/Balance

	Name       string
	MarketType MarketType

	Logger Logger // Logger for this adapter
	// contains filtered or unexported fields
}

BaseAdapter is designed to be embedded in specific exchange adapters. It provides a unified implementation for common adapter requirements: - Connection tracking (WS Market, WS Order, WS Account) - Local OrderBook mapping and readiness waiting - Symbol detail caching - Local state management (Orders, Positions, Balance) via embedding LocalStateManager - Automatic order validation and slippage handling

func NewBaseAdapter

func NewBaseAdapter(name string, marketType MarketType, logger Logger) *BaseAdapter

NewBaseAdapter creates a new initialized BaseAdapter

func (*BaseAdapter) AcquireRate

func (b *BaseAdapter) AcquireRate(ctx context.Context, method string) error

AcquireRate blocks until the rate limit allows this method to proceed. Checks ban status first — if banned, blocks until ban expires or ctx is cancelled. If no rateLimiter is configured, still checks ban status. Concrete adapters call this at the start of each REST method.

func (*BaseAdapter) ApplySlippage

func (b *BaseAdapter) ApplySlippage(
	ctx context.Context,
	params *OrderParams,
	fetchTicker func(ctx context.Context, symbol string) (*Ticker, error),
) error

ApplySlippage converts a MARKET order with Slippage>0 into a LIMIT IOC order. The fetchTicker function is injected by the concrete adapter.

func (*BaseAdapter) BanStatus

func (b *BaseAdapter) BanStatus() (banned bool, until time.Time)

BanStatus returns current ban status for monitoring.

func (*BaseAdapter) GetExchange

func (b *BaseAdapter) GetExchange() string

GetExchange returns the exchange name

func (*BaseAdapter) GetLocalOrderBook

func (b *BaseAdapter) GetLocalOrderBook(symbol string, depth int) *OrderBook

GetLocalOrderBook returns the standard OrderBook struct from the local WS-maintained orderbook. This satisfies the Exchange interface requirement.

func (*BaseAdapter) GetLocalOrderBookImplementation

func (b *BaseAdapter) GetLocalOrderBookImplementation(symbol string) (LocalOrderBook, bool)

GetLocalOrderBookImplementation returns the underlying LocalOrderBook implementation

func (*BaseAdapter) GetMarketType

func (b *BaseAdapter) GetMarketType() MarketType

GetMarketType returns the market type

func (*BaseAdapter) GetOrderMode

func (b *BaseAdapter) GetOrderMode() OrderMode

GetOrderMode returns the current order mode (defaults to WS).

func (*BaseAdapter) GetSymbolDetail

func (b *BaseAdapter) GetSymbolDetail(symbol string) (*SymbolDetails, error)

GetSymbolDetail returns the cached detail for a symbol

func (*BaseAdapter) IsAccountConnected

func (b *BaseAdapter) IsAccountConnected() bool

IsAccountConnected checks if account WS is connected

func (*BaseAdapter) IsMarketConnected

func (b *BaseAdapter) IsMarketConnected() bool

IsMarketConnected checks if market WS is connected

func (*BaseAdapter) IsOrderConnected

func (b *BaseAdapter) IsOrderConnected() bool

IsOrderConnected checks if order WS is connected

func (*BaseAdapter) IsRESTMode

func (b *BaseAdapter) IsRESTMode() bool

IsRESTMode returns true if orders should use REST/HTTP transport.

func (*BaseAdapter) ListSymbols

func (b *BaseAdapter) ListSymbols() []string

ListSymbols returns all symbols in the symbol details cache. These are base currency symbols (e.g. "BTC", "ETH") loaded at adapter init.

func (*BaseAdapter) MarkAccountConnected

func (b *BaseAdapter) MarkAccountConnected()

MarkAccountConnected marks the account websocket as connected

func (*BaseAdapter) MarkMarketConnected

func (b *BaseAdapter) MarkMarketConnected()

MarkMarketConnected marks the market websocket as connected

func (*BaseAdapter) MarkOrderConnected

func (b *BaseAdapter) MarkOrderConnected()

MarkOrderConnected marks the order websocket as connected

func (*BaseAdapter) RateLimitStats

func (b *BaseAdapter) RateLimitStats() []ratelimit.BucketStats

RateLimitStats returns current rate limit usage for monitoring. Returns nil if no rate limiter is configured.

func (*BaseAdapter) RecordBan

func (b *BaseAdapter) RecordBan(err error) bool

RecordBan checks if an error indicates an IP ban and records it. Call this after any REST method that returns an error. Returns true if a ban was detected.

func (*BaseAdapter) RemoveLocalOrderBook

func (b *BaseAdapter) RemoveLocalOrderBook(symbol string)

RemoveLocalOrderBook removes a local orderbook

func (*BaseAdapter) SetLocalOrderBook

func (b *BaseAdapter) SetLocalOrderBook(symbol string, ob LocalOrderBook)

SetLocalOrderBook registers an instantiated LocalOrderBook implementation

func (*BaseAdapter) SetOrderMode

func (b *BaseAdapter) SetOrderMode(mode OrderMode)

SetOrderMode sets whether order operations use WS or REST transport.

func (*BaseAdapter) SetSymbolDetails

func (b *BaseAdapter) SetSymbolDetails(details map[string]*SymbolDetails)

SetSymbolDetails replaces the entire symbol details cache

func (*BaseAdapter) ValidateOrder

func (b *BaseAdapter) ValidateOrder(params *OrderParams) error

ValidateOrder validates and auto-formats order params using cached symbol details. Call this at the start of PlaceOrder in every adapter.

func (*BaseAdapter) WaitOrderBookReady

func (b *BaseAdapter) WaitOrderBookReady(ctx context.Context, symbol string) error

WaitOrderBookReady waits for a specific subscribed orderbook to be ready.

func (*BaseAdapter) WithRateLimiter

func (b *BaseAdapter) WithRateLimiter(rules []ratelimit.RateLimitRule, weights map[string][]ratelimit.CategoryWeight)

WithRateLimiter configures rate limiting for this adapter. Called by each exchange's constructor with exchange-specific rules and weights.

type ErrBanned

type ErrBanned struct {
	Until time.Time
}

ErrBanned is returned when a request is blocked due to an active IP ban.

func (*ErrBanned) Error

func (e *ErrBanned) Error() string

type Exchange

type Exchange interface {
	// === Identity ===
	GetExchange() string
	GetMarketType() MarketType
	Close() error

	// === Symbol Mapping ===
	// FormatSymbol converts a base symbol (e.g. "BTC") to exchange-specific format.
	FormatSymbol(symbol string) string
	// ExtractSymbol converts an exchange-specific symbol back to base symbol.
	ExtractSymbol(symbol string) string
	// ListSymbols returns all symbols supported by this adapter.
	ListSymbols() []string

	// === Market Data (REST) ===
	FetchTicker(ctx context.Context, symbol string) (*Ticker, error)
	FetchOrderBook(ctx context.Context, symbol string, limit int) (*OrderBook, error)
	FetchTrades(ctx context.Context, symbol string, limit int) ([]Trade, error)
	FetchKlines(ctx context.Context, symbol string, interval Interval, opts *KlineOpts) ([]Kline, error)

	// === Trading ===
	PlaceOrder(ctx context.Context, params *OrderParams) (*Order, error)
	CancelOrder(ctx context.Context, orderID, symbol string) error
	CancelAllOrders(ctx context.Context, symbol string) error
	FetchOrder(ctx context.Context, orderID, symbol string) (*Order, error)
	FetchOpenOrders(ctx context.Context, symbol string) ([]Order, error)

	// === Account ===
	FetchAccount(ctx context.Context) (*Account, error)
	FetchBalance(ctx context.Context) (decimal.Decimal, error)
	FetchSymbolDetails(ctx context.Context, symbol string) (*SymbolDetails, error)
	FetchFeeRate(ctx context.Context, symbol string) (*FeeRate, error)

	// === Local OrderBook (WS-maintained) ===
	// WatchOrderBook subscribes to orderbook updates and maintains a local copy.
	// The callback is called on every update; pass nil for pull-only mode.
	// This method blocks until the initial snapshot is synced.
	WatchOrderBook(ctx context.Context, symbol string, cb OrderBookCallback) error
	GetLocalOrderBook(symbol string, depth int) *OrderBook
	StopWatchOrderBook(ctx context.Context, symbol string) error

	// === WebSocket Streaming ===
	Streamable
}

Exchange is the primary interface for strategy developers. It provides a unified, CCXT-inspired API for interacting with any exchanges.

Symbol convention: all methods accept a **base currency** symbol (e.g. "BTC", "ETH"). The adapter handles conversion to echange-specific formats internally.

Method naming convention: Fetch* = REST query, Watch* = WebSocket subscription.

type ExchangeError

type ExchangeError struct {
	Exchange string // Exchange name, e.g. "BINANCE"
	Code     string // Exchange-specific error code
	Message  string // Original error message from exchange
	Err      error  // Sentinel error for errors.Is matching
}

ExchangeError wraps an exchange-specific error with a sentinel cause. Use errors.Is(err, adapter.ErrInsufficientBalance) for structured handling.

func NewExchangeError

func NewExchangeError(exchange, code, message string, sentinel error) *ExchangeError

NewExchangeError creates a new ExchangeError.

func (*ExchangeError) Error

func (e *ExchangeError) Error() string

func (*ExchangeError) Unwrap

func (e *ExchangeError) Unwrap() error

type FeeRate

type FeeRate struct {
	Maker decimal.Decimal `json:"maker"`
	Taker decimal.Decimal `json:"taker"`
}

FeeRate represents maker/taker fee rates for a symbol.

type FundingRate

type FundingRate struct {
	Symbol               string          `json:"symbol"`
	FundingRate          decimal.Decimal `json:"funding_rate"`
	FundingIntervalHours int64           `json:"funding_interval_hours"`
	FundingTime          int64           `json:"funding_time"`
	NextFundingTime      int64           `json:"next_funding_time"`
	UpdateTime           int64           `json:"update_time"`
}

FundingRate represents the funding rate for a perpetual futures symbol.

type Interval

type Interval string

Interval represents the candlestick/kline time period.

const (
	Interval1m  Interval = "1m"
	Interval3m  Interval = "3m"
	Interval5m  Interval = "5m"
	Interval15m Interval = "15m"
	Interval30m Interval = "30m"
	Interval1h  Interval = "1h"
	Interval2h  Interval = "2h"
	Interval4h  Interval = "4h"
	Interval6h  Interval = "6h"
	Interval8h  Interval = "8h"
	Interval12h Interval = "12h"
	Interval1d  Interval = "1d"
	Interval3d  Interval = "3d"
	Interval1w  Interval = "1w"
	Interval1M  Interval = "1M"
)

type IsolatedMarginAccount

type IsolatedMarginAccount struct {
	Assets            []IsolatedMarginSymbol `json:"assets"`
	TotalAssetBTC     decimal.Decimal        `json:"total_asset_btc"`
	TotalLiabilityBTC decimal.Decimal        `json:"total_liability_btc"`
	TotalNetAssetBTC  decimal.Decimal        `json:"total_net_asset_btc"`
}

IsolatedMarginAccount represents an isolated margin account summary.

type IsolatedMarginAsset

type IsolatedMarginAsset struct {
	Asset         string          `json:"asset"`
	BorrowEnabled bool            `json:"borrow_enabled"`
	Borrowed      decimal.Decimal `json:"borrowed"`
	Free          decimal.Decimal `json:"free"`
	Interest      decimal.Decimal `json:"interest"`
	Locked        decimal.Decimal `json:"locked"`
	NetAsset      decimal.Decimal `json:"net_asset"`
	TotalAsset    decimal.Decimal `json:"total_asset"`
}

IsolatedMarginAsset represents a single asset in an isolated margin account.

type IsolatedMarginSymbol

type IsolatedMarginSymbol struct {
	Symbol         string              `json:"symbol"`
	BaseAsset      IsolatedMarginAsset `json:"base_asset"`
	QuoteAsset     IsolatedMarginAsset `json:"quote_asset"`
	MarginLevel    decimal.Decimal     `json:"margin_level"`
	MarginRatio    decimal.Decimal     `json:"margin_ratio"`
	IndexPrice     decimal.Decimal     `json:"index_price"`
	LiquidatePrice decimal.Decimal     `json:"liquidate_price"`
	LiquidateRate  decimal.Decimal     `json:"liquidate_rate"`
	Enabled        bool                `json:"enabled"`
}

IsolatedMarginSymbol represents an isolated margin trading pair.

type Kline

type Kline struct {
	Symbol    string          `json:"symbol"`
	Interval  Interval        `json:"interval"`
	Open      decimal.Decimal `json:"open"`
	High      decimal.Decimal `json:"high"`
	Low       decimal.Decimal `json:"low"`
	Close     decimal.Decimal `json:"close"`
	Volume    decimal.Decimal `json:"volume"`    // Base currency volume
	QuoteVol  decimal.Decimal `json:"quote_vol"` // Quote currency volume
	Timestamp int64           `json:"timestamp"` // Open time in milliseconds
}

Kline represents a single candlestick/OHLCV bar.

type KlineCallback

type KlineCallback func(*Kline)

type KlineOpts

type KlineOpts struct {
	Start *time.Time
	End   *time.Time
	Limit int
}

KlineOpts provides optional parameters for FetchKlines.

type Level

type Level struct {
	Price    decimal.Decimal `json:"price"`
	Quantity decimal.Decimal `json:"quantity"`
}

Level represents a single price level in the order book.

type LocalOrderBook

type LocalOrderBook interface {
	// GetDepth returns the sorted top `limit` depth levels.
	// Bids are sorted descending (highest price first).
	// Asks are sorted ascending (lowest price first).
	GetDepth(limit int) ([]Level, []Level)

	// WaitReady blocks until the orderbook is initialized or the timeout expires.
	WaitReady(ctx context.Context, timeout time.Duration) bool

	// Timestamp returns the Unix millisecond timestamp of the last update.
	Timestamp() int64
}

LocalOrderBook interface standardizes the output of locally maintained orderbooks. This allows the BaseAdapter and upper logic layers to consume depth data uniformly, regardless of whether the internal sync uses delta snapshots, buffer timestamps, or gapless polling.

Each exchange implements this interface in its own orderbook.go file because synchronization protocols differ (Binance: diff+snapshot, Nado: gap detection, OKX: checksum validation, etc.).

type LocalStateManager

type LocalStateManager struct {
	// contains filtered or unexported fields
}

LocalStateManager provides thread-safe local state management for adapters. It tracks Orders, Positions, and Balances, typically updated via WebSocket streams. Unlike LocalOrderBook (which is per-exchange), this is a shared concrete implementation because order/position state management logic is identical across all exchanges.

func NewLocalStateManager

func NewLocalStateManager(logger Logger) *LocalStateManager

NewLocalStateManager initializes a new LocalStateManager

func (*LocalStateManager) ApplyOrderUpdate

func (m *LocalStateManager) ApplyOrderUpdate(o *Order)

ApplyOrderUpdate applies an incremental order update

func (*LocalStateManager) ApplyPositionUpdate

func (m *LocalStateManager) ApplyPositionUpdate(p *Position)

ApplyPositionUpdate applies an incremental position update

func (*LocalStateManager) Close

func (m *LocalStateManager) Close()

Close closes the LocalStateManager (channels cleaned up by GC).

func (*LocalStateManager) GetAllOpenOrders

func (m *LocalStateManager) GetAllOpenOrders() []Order

GetAllOpenOrders returns a list of all current open orders

func (*LocalStateManager) GetAllPositions

func (m *LocalStateManager) GetAllPositions() []Position

GetAllPositions returns a list of all positions

func (*LocalStateManager) GetBalance

func (m *LocalStateManager) GetBalance() decimal.Decimal

GetBalance returns the cached total balance

func (*LocalStateManager) GetOrder

func (m *LocalStateManager) GetOrder(orderID string) (*Order, bool)

GetOrder returns a copy of the desired order if it exists locally

func (*LocalStateManager) GetOrderStream

func (m *LocalStateManager) GetOrderStream() <-chan *Order

GetOrderStream gets the read-only channel for order updates

func (*LocalStateManager) GetPosition

func (m *LocalStateManager) GetPosition(symbol string) (*Position, bool)

GetPosition returns a copy of the desired position if it exists locally

func (*LocalStateManager) GetPositionStream

func (m *LocalStateManager) GetPositionStream() <-chan *Position

GetPositionStream gets the read-only channel for position updates

func (*LocalStateManager) IsInitialized

func (m *LocalStateManager) IsInitialized() bool

IsInitialized returns whether state has been populated

func (*LocalStateManager) SetInitialState

func (m *LocalStateManager) SetInitialState(balance decimal.Decimal, positions []Position, orders []Order)

SetInitialState populates the state from a REST API snapshot

func (*LocalStateManager) UpdateBalance

func (m *LocalStateManager) UpdateBalance(balance decimal.Decimal)

UpdateBalance applies an incremental balance update

type Logger

type Logger interface {
	Debugw(msg string, keysAndValues ...any)
	Infow(msg string, keysAndValues ...any)
	Warnw(msg string, keysAndValues ...any)
	Errorw(msg string, keysAndValues ...any)
}

Logger is the logging interface used throughout the library. It is compatible with *zap.SugaredLogger out of the box.

Usage:

// With zap:
logger := zap.NewProduction().Sugar()
adp, err := binance.NewAdapter(ctx, binance.Options{Logger: logger})

// With NopLogger (default when no logger is provided):
adp, err := binance.NewAdapter(ctx, binance.Options{})
var NopLogger Logger = nopLogger{}

NopLogger discards all log output. This is the default when no logger is provided.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager manages multiple exchange adapters

func NewManager

func NewManager() *Manager

NewManager creates a new adapter manager

func (*Manager) CloseAll

func (m *Manager) CloseAll() error

CloseAll closes all adapters

func (*Manager) GetAdapter

func (m *Manager) GetAdapter(name string) (Exchange, error)

GetAdapter gets the adapter for a specific exchange

func (*Manager) GetAllAdapters

func (m *Manager) GetAllAdapters() []Exchange

GetAllAdapters returns all registered adapters

func (*Manager) GetExchangeNames

func (m *Manager) GetExchangeNames() []string

GetExchangeNames returns sorted list of registered exchange names

func (*Manager) Register

func (m *Manager) Register(name string, adp Exchange)

Register registers an adapter

type MarginAccount

type MarginAccount struct {
	MarginLevel       decimal.Decimal `json:"margin_level"`
	TotalAssetBTC     decimal.Decimal `json:"total_asset_btc"`
	TotalLiabilityBTC decimal.Decimal `json:"total_liability_btc"`
	TotalNetAssetBTC  decimal.Decimal `json:"total_net_asset_btc"`
	UserAssets        []MarginAsset   `json:"user_assets"`
}

MarginAccount represents a cross-margin account summary.

type MarginAsset

type MarginAsset struct {
	Asset    string          `json:"asset"`
	Borrowed decimal.Decimal `json:"borrowed"`
	Free     decimal.Decimal `json:"free"`
	Interest decimal.Decimal `json:"interest"`
	Locked   decimal.Decimal `json:"locked"`
	NetAsset decimal.Decimal `json:"net_asset"`
}

MarginAsset represents a single asset in a margin account.

type MarginType

type MarginType string
const (
	MarginTypeCrossed  MarginType = "CROSSED"
	MarginTypeIsolated MarginType = "ISOLATED"
	MarginTypeCash     MarginType = "CASH"
)

type MarketType

type MarketType string

MarketType represents the type of trading market.

const (
	MarketTypeSpot MarketType = "spot" // Spot trading
	MarketTypePerp MarketType = "perp" // Perpetual futures
)

type ModifyOrderParams

type ModifyOrderParams struct {
	Quantity decimal.Decimal
	Price    decimal.Decimal
}

ModifyOrderParams specifies parameters for modifying an existing order.

type Order

type Order struct {
	OrderID        string          `json:"order_id"`
	Symbol         string          `json:"symbol"`
	Side           OrderSide       `json:"side"`
	Type           OrderType       `json:"type"`
	Quantity       decimal.Decimal `json:"quantity"`
	Price          decimal.Decimal `json:"price,omitempty"`
	Status         OrderStatus     `json:"status"`
	FilledQuantity decimal.Decimal `json:"filled_quantity"`
	Timestamp      int64           `json:"timestamp"`
	Fee            decimal.Decimal `json:"fee,omitempty"`
	ClientOrderID  string          `json:"client_order_id,omitempty"`
	ReduceOnly     bool            `json:"reduce_only,omitempty"`
	TimeInForce    TimeInForce     `json:"time_in_force,omitempty"`
}

Order represents a trading order with its current state.

func PlaceLimitOrder

func PlaceLimitOrder(ctx context.Context, adp Exchange, symbol string, side OrderSide, price, qty decimal.Decimal) (*Order, error)

PlaceLimitOrder is a convenience function for placing a limit order.

func PlaceMarketOrder

func PlaceMarketOrder(ctx context.Context, adp Exchange, symbol string, side OrderSide, qty decimal.Decimal) (*Order, error)

PlaceMarketOrder is a convenience function for placing a market order.

func PlaceMarketOrderWithSlippage

func PlaceMarketOrderWithSlippage(ctx context.Context, adp Exchange, symbol string, side OrderSide, qty, slippage decimal.Decimal) (*Order, error)

PlaceMarketOrderWithSlippage is a convenience function for placing a market order with slippage protection.

type OrderBook

type OrderBook struct {
	Symbol    string  `json:"symbol"`
	Bids      []Level `json:"bids"` // Sorted descending by price
	Asks      []Level `json:"asks"` // Sorted ascending by price
	Timestamp int64   `json:"timestamp"`
}

OrderBook represents a snapshot of the order book.

type OrderBookCallback

type OrderBookCallback func(*OrderBook)

type OrderMode

type OrderMode string

OrderMode controls whether trading operations (PlaceOrder, CancelOrder, etc.) use WebSocket or REST/HTTP transport.

const (
	// OrderModeWS uses WebSocket for order operations (default, lower latency).
	OrderModeWS OrderMode = "ws"
	// OrderModeREST uses REST/HTTP for order operations (no persistent connection needed).
	OrderModeREST OrderMode = "rest"
)

type OrderParams

type OrderParams struct {
	Symbol      string
	Side        OrderSide
	Type        OrderType // MARKET or LIMIT
	Quantity    decimal.Decimal
	Price       decimal.Decimal // Required for LIMIT; ignored for MARKET (unless Slippage > 0)
	TimeInForce TimeInForce     // Default: GTC for LIMIT
	ReduceOnly  bool
	Slippage    decimal.Decimal // If > 0 and Type == MARKET, auto-applies slippage logic
	ClientID    string          // Client-defined order ID
}

OrderParams is the unified parameter struct for PlaceOrder.

type OrderSide

type OrderSide string

OrderSide represents the direction of an order (buy or sell).

const (
	OrderSideBuy  OrderSide = "BUY"
	OrderSideSell OrderSide = "SELL"
)

type OrderStatus

type OrderStatus string

OrderStatus represents the state of an order.

const (
	OrderStatusPending         OrderStatus = "PENDING"
	OrderStatusPartiallyFilled OrderStatus = "PARTIALLY_FILLED"
	OrderStatusFilled          OrderStatus = "FILLED"
	OrderStatusCancelled       OrderStatus = "CANCELLED"
	OrderStatusRejected        OrderStatus = "REJECTED"
	OrderStatusNew             OrderStatus = "NEW"
	OrderStatusUnknown         OrderStatus = "UNKNOWN"
)

type OrderType

type OrderType string

OrderType represents the type of an order.

const (
	OrderTypeLimit            OrderType = "LIMIT"
	OrderTypeMarket           OrderType = "MARKET"
	OrderTypeStopLossLimit    OrderType = "STOP_LOSS_LIMIT"
	OrderTypeTakeProfitLimit  OrderType = "TAKE_PROFIT_LIMIT"
	OrderTypeStopLossMarket   OrderType = "STOP_LOSS_MARKET"
	OrderTypeTakeProfitMarket OrderType = "TAKE_PROFIT_MARKET"
	OrderTypePostOnly         OrderType = "POST_ONLY"
	OrderTypeUnknown          OrderType = "UNKNOWN"
)

type OrderUpdateCallback

type OrderUpdateCallback func(*Order)

type PerpExchange

type PerpExchange interface {
	Exchange
	FetchPositions(ctx context.Context) ([]Position, error)
	SetLeverage(ctx context.Context, symbol string, leverage int) error
	FetchFundingRate(ctx context.Context, symbol string) (*FundingRate, error)
	FetchAllFundingRates(ctx context.Context) ([]FundingRate, error)
	ModifyOrder(ctx context.Context, orderID, symbol string, params *ModifyOrderParams) (*Order, error)
}

PerpExchange extends Exchange with perpetual futures capabilities. Use type assertion: if perp, ok := adp.(adapter.PerpExchange); ok { ... }

type Position

type Position struct {
	Symbol            string          `json:"symbol"`
	Side              PositionSide    `json:"side"`
	Quantity          decimal.Decimal `json:"quantity"`
	EntryPrice        decimal.Decimal `json:"entry_price"`
	UnrealizedPnL     decimal.Decimal `json:"unrealized_pnl"`
	RealizedPnL       decimal.Decimal `json:"realized_pnl"`
	LiquidationPrice  decimal.Decimal `json:"liquidation_price,omitempty"`
	Leverage          decimal.Decimal `json:"leverage,omitempty"`
	MaintenanceMargin decimal.Decimal `json:"maintenance_margin,omitempty"`
	MarginType        string          `json:"margin_type,omitempty"` // ISOLATED or CROSSED
}

Position represents an open position in a perpetual futures market.

type PositionSide

type PositionSide string

PositionSide represents the direction of a position.

const (
	PositionSideLong  PositionSide = "LONG"
	PositionSideShort PositionSide = "SHORT"
	PositionSideBoth  PositionSide = "BOTH" // For one-way mode
)

type PositionUpdateCallback

type PositionUpdateCallback func(*Position)

type QuoteCurrency added in v0.1.2

type QuoteCurrency string

QuoteCurrency represents the quote/settlement currency of a trading pair.

const (
	QuoteCurrencyUSDT QuoteCurrency = "USDT"
	QuoteCurrencyUSDC QuoteCurrency = "USDC"
	QuoteCurrencyDUSD QuoteCurrency = "DUSD"
)

type SpotBalance

type SpotBalance struct {
	Asset  string          `json:"asset"`  // Currency symbol, e.g. "BTC", "USDT"
	Free   decimal.Decimal `json:"free"`   // Available balance
	Locked decimal.Decimal `json:"locked"` // Frozen/locked balance
	Total  decimal.Decimal `json:"total"`  // Total balance (Free + Locked)
}

SpotBalance represents the balance of a single asset in a spot account.

type SpotExchange

type SpotExchange interface {
	Exchange
	FetchSpotBalances(ctx context.Context) ([]SpotBalance, error)
	TransferAsset(ctx context.Context, params *TransferParams) error
}

SpotExchange extends Exchange with spot-specific capabilities.

type Streamable

type Streamable interface {
	WatchOrders(ctx context.Context, cb OrderUpdateCallback) error
	WatchPositions(ctx context.Context, cb PositionUpdateCallback) error
	WatchTicker(ctx context.Context, symbol string, cb TickerCallback) error
	WatchTrades(ctx context.Context, symbol string, cb TradeCallback) error
	WatchKlines(ctx context.Context, symbol string, interval Interval, cb KlineCallback) error
	StopWatchOrders(ctx context.Context) error
	StopWatchPositions(ctx context.Context) error
	StopWatchTicker(ctx context.Context, symbol string) error
	StopWatchTrades(ctx context.Context, symbol string) error
	StopWatchKlines(ctx context.Context, symbol string, interval Interval) error
}

Streamable provides WebSocket streaming capabilities. All Watch methods accept a callback. Not all exchanges support all stream types.

type SymbolDetails

type SymbolDetails struct {
	Symbol            string          `json:"symbol"`
	PricePrecision    int32           `json:"price_precision"`    // Decimal places for price
	QuantityPrecision int32           `json:"quantity_precision"` // Decimal places for quantity
	MinQuantity       decimal.Decimal `json:"min_quantity"`       // Minimum order quantity
	MinNotional       decimal.Decimal `json:"min_notional"`       // Minimum notional value (price * qty)
}

SymbolDetails provides trading rules and precision for a symbol.

type Ticker

type Ticker struct {
	Symbol     string          `json:"symbol"`
	LastPrice  decimal.Decimal `json:"last_price"`
	IndexPrice decimal.Decimal `json:"index_price"`
	MarkPrice  decimal.Decimal `json:"mark_price"`
	MidPrice   decimal.Decimal `json:"mid_price"`
	Bid        decimal.Decimal `json:"bid"` // Best Bid
	Ask        decimal.Decimal `json:"ask"` // Best Ask
	Volume24h  decimal.Decimal `json:"volume_24h"`
	QuoteVol   decimal.Decimal `json:"quote_vol"` // Quote Volume
	High24h    decimal.Decimal `json:"high_24h"`
	Low24h     decimal.Decimal `json:"low_24h"`
	Timestamp  int64           `json:"timestamp"`
}

Ticker represents real-time market data for a symbol.

type TickerCallback

type TickerCallback func(*Ticker)

type TimeInForce

type TimeInForce string

TimeInForce specifies how long an order remains active.

const (
	TimeInForceGTC TimeInForce = "GTC" // Good Till Cancel
	TimeInForceIOC TimeInForce = "IOC" // Immediate Or Cancel
	TimeInForceFOK TimeInForce = "FOK" // Fill Or Kill
	TimeInForcePO  TimeInForce = "PO"  // Post Only
)

type Trade

type Trade struct {
	ID        string          `json:"id"`
	Symbol    string          `json:"symbol"`
	Price     decimal.Decimal `json:"price"`
	Quantity  decimal.Decimal `json:"quantity"`
	Side      TradeSide       `json:"side"`
	Timestamp int64           `json:"timestamp"` // Milliseconds
}

Trade represents a single market trade.

type TradeCallback

type TradeCallback func(*Trade)

type TradeSide

type TradeSide string

TradeSide 成交方向 (for market trades)

const (
	TradeSideBuy  TradeSide = "buy"
	TradeSideSell TradeSide = "sell"
)

type TransferParams

type TransferParams struct {
	Asset       string          // Currency symbol
	Amount      decimal.Decimal // Transfer amount
	FromAccount AccountType     // Source account type
	ToAccount   AccountType     // Destination account type
}

Directories

Path Synopsis
sdk
sdk
sdk
sdk
okx
sdk
Package ratelimit provides a generic, declarative rate limiting engine.
Package ratelimit provides a generic, declarative rate limiting engine.
sdk

Jump to

Keyboard shortcuts

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