trade

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 13, 2026 License: MIT Imports: 6 Imported by: 0

README

go-trade

CI Go Reference Go Latest Release GitHub Stars

Go library providing a unified data model for aggregating market data across multiple exchanges. Defines exchange-agnostic types for candles, time-and-sale transactions, order books, orders, instruments, symbols, and currencies — serving as the common schema for normalizing data from Binance, CME, NASDAQ, and other trading venues.

Architecture

graph TB
    subgraph "Exchange Connectors"
        BIN["Binance"]
        CME["CME Group"]
        NAS["NASDAQ"]
        FX["Forex Brokers"]
        CEX["Other CEX/DEX"]
    end

    subgraph "go-trade — Unified Data Model"
        TAS["TimeAndSale<br/>Atomic trade events"]
        CND["Candle<br/>OHLC + microstructure"]
        OB["OrderBook<br/>Bid/Ask snapshots"]
        ORD["Order<br/>Trade orders"]
        INS["Instrument<br/>Tradeable assets"]
        MKT["Market<br/>Trading pairs"]
        SYM["Symbol<br/>Hierarchical asset tree"]
        CUR["currency.Provider<br/>170+ fiat, 60+ crypto"]
    end

    subgraph "Storage & Analysis"
        DB["TimescaleDB<br/>PostgreSQL"]
        PQ["Parquet Files"]
        DASH["Analytics<br/>Dashboard"]
    end

    BIN -->|"normalize"| TAS
    CME -->|"normalize"| TAS
    NAS -->|"normalize"| TAS
    FX -->|"normalize"| TAS
    CEX -->|"normalize"| TAS

    TAS --> CND
    TAS --> OB

    TAS --> DB
    CND --> DB
    OB --> PQ
    ORD --> DB

    DB --> DASH
    PQ --> DASH

    INS -.->|"classifies"| TAS
    MKT -.->|"identifies"| INS
    SYM -.->|"defines"| MKT
    CUR -.->|"resolves"| SYM

Data Flow

sequenceDiagram
    participant Exchange
    participant Connector
    participant Model as go-trade Model
    participant Store

    Exchange->>Connector: Raw trade event (JSON/WebSocket)
    Connector->>Connector: Parse exchange-specific format
    Connector->>Model: trade.TimeAndSale{Ticker, Price, Volume, Side}
    Model->>Store: Normalized row

    Note over Model: Same struct regardless<br/>of source exchange

    Exchange->>Connector: Raw candle data
    Connector->>Model: trade.Candle{OHLC, Clusters, DeltaLevels}
    Model->>Store: Normalized candle

    Store->>Store: Cross-exchange aggregation

Cross-Exchange Aggregation

graph LR
    subgraph "BTC/USDT Trades"
        B1["Binance<br/>$97,420 × 0.5 BTC"]
        B2["Coinbase<br/>$97,418 × 1.2 BTC"]
        B3["Kraken<br/>$97,422 × 0.8 BTC"]
    end

    subgraph "Unified TimeAndSale"
        T["trade.TimeAndSale<br/>• Ticker: BTCUSDT<br/>• ExchangeID: varies<br/>• Price / Volume / Side"]
    end

    subgraph "Aggregated Candle"
        C["trade.Candle<br/>• OHLC across all venues<br/>• PriceClusters by level<br/>• DeltaLevels (buy vs sell)<br/>• VolumeLevels"]
    end

    B1 --> T
    B2 --> T
    B3 --> T
    T --> C

Symbol Hierarchy

Symbols form a tree that links base assets to their derivatives and stablecoins, enabling cross-exchange normalization:

graph TD
    USD["USD (fiat)"]
    BTC["BTC (crypto)"]
    ETH["ETH (crypto)"]

    USD --> USDT["USDT — stablecoin"]
    USD --> USDC["USDC — stablecoin"]
    USD --> EUR["EUR (fiat)"]
    USD --> GBP["GBP (fiat)"]

    BTC --> BTCFT["BTCFT — futures token"]
    BTC --> BTCM24["BTCM24 — Jun 2024 future"]
    BTC --> WBTC["WBTC — wrapped"]

    ETH --> STETH["stETH — liquid staking"]
    ETH --> ETHM24["ETHM24 — Jun 2024 future"]

    style USD fill:#4CAF50,color:#fff
    style BTC fill:#F7931A,color:#fff
    style ETH fill:#627EEA,color:#fff

Installation

go get github.com/eslider/go-trade

Features

  • Candle model — OHLC + ask/bid, price clusters, delta/volume levels, price snake
  • TimeAndSale — Atomic trade events with exchange ID, data feed provider, aggressor side
  • OrderBook — Bid/ask snapshots with timestamps
  • Order — Custom JSON unmarshaling for string-encoded fields from exchange APIs
  • Symbol — Hierarchical asset tree (fiat/crypto) with parent-child relationships for derivatives
  • Instrument / Market — Asset classification (spot, future, option, FX) and trading pairs
  • Currency provider — Embedded 170+ fiat currencies and 60+ crypto tokens with lookup and filtering
  • DateTime / UUID — JSON-aware wrappers for exchange date formats and UUIDs

Quick Start

Candle Analysis
candle := trade.Candle{
    Open: 100.0, High: 110.0, Low: 95.0, Close: 108.0,
    Ask: 108.5, Bid: 107.5,
    TimeOpen:  time.Now().Add(-5 * time.Minute),
    TimeClose: time.Now(),
}

fmt.Println("Bullish:", candle.IsBullish())   // true
fmt.Println("Range:", candle.Range())          // 15.0
fmt.Println("Spread:", candle.Spread())        // 1.0
fmt.Println("Duration:", candle.Duration())    // 5m0s
Time & Sale Recording
event := trade.TimeAndSale{
    Ticker:     "BTCUSDT",
    ExchangeID: 1,  // Binance
    Time:       time.Now(),
    Sale: trade.Sale{
        Price:         97420.50,
        AggressorSide: trade.AggressorBuy,
        Volume:        5,
    },
}
fmt.Printf("%s: %s @ $%.2f (%s)\n",
    event.Ticker, event.Sale.AggressorSide,
    event.Sale.Price, event.Time.Format(time.RFC3339))
Currency Lookup
import "github.com/eslider/go-trade/currency"

provider, _ := currency.New()

btc := provider.Currencies.Get("BTC")
fmt.Println(btc.Description) // "Bitcoin"
fmt.Println(btc.IsCrypto())  // true

fiats := provider.Currencies.Fiats()
fmt.Printf("%d fiat currencies loaded\n", len(fiats))

cryptos := provider.Currencies.Cryptos()
fmt.Printf("%d cryptocurrencies loaded\n", len(cryptos))
Symbol Tree
symbols := trade.Symbols{
    {ID: 1, Type: trade.SymbolFiat, Code: "USD", Name: "US Dollar"},
    {ID: 2, Type: trade.SymbolCrypto, ParentID: 1, Code: "USDT", Name: "Tether"},
    {ID: 3, Type: trade.SymbolCrypto, ParentID: 1, Code: "USDC", Name: "USD Coin"},
    {ID: 14, Type: trade.SymbolCrypto, Code: "BTC", Name: "Bitcoin"},
    {ID: 22, Type: trade.SymbolCrypto, ParentID: 14, Code: "BTCFT", Name: "BTC Futures Token"},
}

// Tree navigation
roots := symbols.Roots()               // USD, BTC
btcDerivs := symbols.Children(14)      // BTCFT
usdStables := symbols.Children(1)      // USDT, USDC

// Lookup
btc := symbols.GetByCode("BTC")
fmt.Println(btc.IsCrypto(), btc.IsRoot()) // true true

// Filter
fiats := symbols.Fiats()               // USD
cryptos := symbols.Cryptos()            // USDT, USDC, BTC, BTCFT
Order Deserialization
// Exchange APIs often return numeric fields as strings
raw := []byte(`{
    "order_id": "b68d69564a79dea4776afa33d1d2fcab",
    "customer_id": "41",
    "order_status": "shipped",
    "order_approved_at": "2018-02-28 10:40:35"
}`)

var order trade.Order
json.Unmarshal(raw, &order)
fmt.Println(order.OrderID)    // b68d6956-4a79-dea4-776a-fa33d1d2fcab
fmt.Println(order.CustomerID) // 41 (int64, not string)

Package Structure

go-trade/
├── trade.go               # Package doc
├── candle.go              # Candle (OHLC + microstructure)
├── time_and_sale.go       # Atomic trade events
├── order.go               # Trading orders
├── instrument.go          # Instruments and markets
├── symbol.go              # Hierarchical asset symbols
├── aggressor_side.go      # Buy/sell side enum
├── datetime.go            # Exchange datetime parser
├── uuid.go                # UUID JSON wrapper
├── price_clusters.go      # Volume at price level
├── candle_delta_levels.go # Delta/volume levels
├── trade_test.go          # Unit tests
├── symbol_test.go         # Symbol tests
└── currency/
    ├── currency.go        # Fiat + crypto provider
    ├── currency_test.go   # Currency tests
    └── currencies.yml     # 170+ fiat, 60+ crypto definitions

API Reference

Core Types
Type Description
Candle OHLC candlestick with price clusters, delta levels, and volume profile
TimeAndSale Atomic trade event: price, volume, side, exchange, timestamp
Order Trading order with auto-deserialization from string-encoded JSON
Symbol Trading symbol with type (fiat/crypto) and parent-child hierarchy
Symbols Collection with GetByCode, GetByID, Children, Roots, Fiats, Cryptos
SymbolType Enum: SymbolFiat, SymbolCrypto
Instrument Tradeable asset (spot, future, option, FX)
Market Trading pair (FROM/TO symbols)
OrderBook / OrderBookEntry Bid/ask snapshot at a point in time
Sale Core trade data (price, aggressor side, volume)
PriceClusters Volume and time distribution at a price level
CandleDeltaLevels Min/max delta values within a candle
DateTime JSON-compatible datetime for "2006-01-02 15:04:05" format
UUID JSON-compatible UUID wrapper
Candle Methods
Method Description
IsBullish() Close > Open
IsBearish() Close < Open
IsEmpty() No data
Spread() Ask − Bid
Range() High − Low
Duration() TimeClose − TimeOpen
Symbol Methods
Method Description
IsRoot() ParentID == 0 (top-level asset)
IsFiat() Type == SymbolFiat
IsCrypto() Type == SymbolCrypto
Symbols Collection
Method Description
GetByCode(code) Find symbol by ticker code
GetByID(id) Find symbol by numeric ID
Children(parentID) All symbols with given parent
Roots() All top-level symbols (parent == 0)
Fiats() Filter fiat symbols
Cryptos() Filter crypto symbols
Currency Package
Function Description
currency.New() Load all embedded currency/unit data
Currencies.Get(code) Lookup by code ("BTC", "USD")
Currencies.Cryptos() Filter crypto only
Currencies.Fiats() Filter fiat only

Environment

  • Go 1.22+
  • CI: GitHub Actions (Go 1.22, 1.23, 1.24) with race detection and golangci-lint

License

MIT

Documentation

Overview

Package trade provides a unified data model for aggregating market data across multiple exchanges and data feed providers.

It defines exchange-agnostic types for candles, time-and-sale transactions, order books, orders, price clusters, and market instruments. These models serve as the common schema for normalizing data from Binance, CME, NASDAQ, and other exchanges into a single queryable format.

The currency sub-package provides embedded fiat and cryptocurrency reference data with 170+ fiat currencies and 60+ crypto tokens.

Architecture

Data flows from exchange-specific connectors through these shared types:

Exchange A ──┐
Exchange B ──┼── Connector → trade.TimeAndSale / trade.Candle → Storage
Exchange C ──┘

This decouples storage and analysis from exchange-specific wire formats.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AggressorSide

type AggressorSide int

AggressorSide indicates which side initiated a trade.

const (
	AggressorNone    AggressorSide = iota // No side determined
	AggressorSell                         // Seller initiated
	AggressorBuy                          // Buyer initiated
	AggressorUnknown                      // Side could not be determined
)

func (AggressorSide) String

func (a AggressorSide) String() string

String returns a human-readable representation.

type AskBid

type AskBid struct {
	Ask int64 `json:"ask"`
	Bid int64 `json:"bid"`
}

AskBid holds ask and bid counts.

type AskBidPrice

type AskBidPrice struct {
	Price       float64   `json:"price"`       // Trade price
	AskBid      AskBid    `json:"askBid"`      // Ask/bid counts
	Duration    time.Time `json:"duration"`    // Time delta between trades
	TradesCount int32     `json:"tradesCount"` // Number of events in the deal
}

AskBidPrice represents aggregated trade details within a candlestick.

type Candle

type Candle struct {
	Empty bool `json:"empty,omitempty"`

	// Time
	TimeOpen  time.Time `json:"timeOpen,omitempty"`
	TimeClose time.Time `json:"timeClose,omitempty"`

	// Price
	Open  float64 `json:"open,omitempty"`
	High  float64 `json:"high,omitempty"`
	Low   float64 `json:"low,omitempty"`
	Close float64 `json:"close,omitempty"`
	Ask   float64 `json:"ask,omitempty"`
	Bid   float64 `json:"bid,omitempty"`

	TradesCount   float64                  `json:"tradesCount,omitempty"`
	PriceClusters map[string]PriceClusters `json:"priceClusters,omitempty"`

	DeltaLevels  *CandleDeltaLevels `json:"deltaLevels,omitempty"`
	VolumeLevels *CandleDeltaLevels `json:"volumeLevels,omitempty"`

	PriceSnake []float64 `json:"priceSnake,omitempty"`
}

Candle represents an OHLC candlestick with extended market microstructure data.

func (*Candle) Duration

func (c *Candle) Duration() time.Duration

Duration returns the candle's time span.

func (*Candle) IsBearish

func (c *Candle) IsBearish() bool

IsBearish returns true if the close is below the open.

func (*Candle) IsBullish

func (c *Candle) IsBullish() bool

IsBullish returns true if the close is above the open.

func (*Candle) IsEmpty

func (c *Candle) IsEmpty() bool

IsEmpty returns true if the candle contains no data.

func (*Candle) Range

func (c *Candle) Range() float64

Range returns the high-low price range.

func (*Candle) Spread

func (c *Candle) Spread() float64

Spread returns the ask-bid spread.

type CandleDeltaLevels

type CandleDeltaLevels struct {
	MinDeltaValue float64 `json:"minDeltaValue,omitempty"`
	MinDeltaPrice float64 `json:"minDeltaPrice,omitempty"`
	MaxDeltaValue float64 `json:"maxDeltaValue,omitempty"`
	MaxDeltaPrice float64 `json:"maxDeltaPrice,omitempty"`
}

CandleDeltaLevels holds min/max delta values and their price levels within a candle, used for volume profile and delta analysis.

type DataFeedProvider

type DataFeedProvider struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
	URN  string `json:"urn"`
}

DataFeedProvider identifies a data feed source.

type DateTime

type DateTime struct {
	*time.Time
}

DateTime wraps time.Time with custom JSON unmarshaling using the "2006-01-02 15:04:05" format common in exchange APIs.

func (*DateTime) UnmarshalJSON

func (t *DateTime) UnmarshalJSON(data []byte) (err error)

UnmarshalJSON parses a date-time string in "2006-01-02 15:04:05" format.

type Exchange

type Exchange struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

Exchange identifies a trading exchange.

type Instrument

type Instrument struct {
	ID                 int            `json:"id"`
	Type               InstrumentType `json:"type"`
	Ticker             string         `json:"ticker"`
	Name               string         `json:"name"`
	Description        string         `json:"description,omitempty"`
	ExchangeID         int            `json:"exchangeId,omitempty"`
	DataFeedProviderID int            `json:"dataFeedProviderId,omitempty"`
}

Instrument represents a tradable instrument (e.g. BTCUSDT, ES futures, EUR/USD).

type InstrumentType

type InstrumentType string

InstrumentType classifies a trading instrument.

const (
	InstrumentSpot   InstrumentType = "spot"
	InstrumentFuture InstrumentType = "future"
	InstrumentOption InstrumentType = "option"
	InstrumentFX     InstrumentType = "fx"
)

type Market

type Market struct {
	ID          int    `json:"id"`
	FromSymbol  string `json:"fromSymbol"` // Base (e.g. BTC)
	ToSymbol    string `json:"toSymbol"`   // Quote (e.g. USDT)
	Title       string `json:"title"`
	Description string `json:"description,omitempty"`
}

Market represents a trading pair with base and quote symbols.

func (Market) String

func (m Market) String() string

String returns the market as "FROM/TO".

type Order

type Order struct {
	OrderID               uuid.UUID  `mapstructure:"order_id" json:"orderId"`
	CustomerID            int64      `mapstructure:"customer_id" json:"customerId"`
	Status                string     `mapstructure:"order_status" json:"status"`
	ApprovedAt            *time.Time `mapstructure:"order_approved_at" json:"approvedAt,omitempty"`
	DeliveredToCustomerAt *time.Time `mapstructure:"order_delivered_customer_date" json:"deliveredToCustomerAt,omitempty"`
	DeliveredToCarrierAt  *time.Time `mapstructure:"order_delivered_carrier_date" json:"deliveredToCarrierAt,omitempty"`
	DeliveryEstimatedAt   *time.Time `mapstructure:"order_estimated_delivery_date" json:"deliveryEstimatedAt,omitempty"`
	PurchaseAt            *time.Time `mapstructure:"order_purchase_timestamp" json:"purchaseAt,omitempty"`
}

Order represents a trading order with custom JSON unmarshaling that handles string-encoded numeric fields common in exchange APIs.

func (*Order) UnmarshalJSON

func (r *Order) UnmarshalJSON(data []byte) (err error)

UnmarshalJSON handles string-to-native type conversions for exchange APIs that encode numeric and date fields as strings.

type OrderBook

type OrderBook []OrderBookEntry

OrderBook is a collection of order book snapshots.

type OrderBookEntry

type OrderBookEntry struct {
	Ticker     string    `json:"ticker"`
	ExchangeID int64     `json:"exchangeId"`
	Time       time.Time `json:"time"`
	BestBid    Sale      `json:"bestBid"`
	BestAsk    Sale      `json:"bestAsk"`
}

OrderBookEntry represents a single level in an order book snapshot.

type PriceClusters

type PriceClusters struct {
	Ask      float64 `json:"ask,omitempty"`           // Volume at the ask
	Bid      float64 `json:"bid,omitempty"`           // Volume at the bid
	Duration float64 `json:"durationMilli,omitempty"` // Time at this level (ms)
	Trades   float64 `json:"trades,omitempty"`        // Number of trades
}

PriceClusters describes volume and time distribution at a price level.

type Sale

type Sale struct {
	Price         float64       `json:"price"`         // Trade price
	AggressorSide AggressorSide `json:"aggressorSide"` // Buy or sell initiated
	Volume        int           `json:"volume"`        // Quantity of contracts/shares
}

Sale holds the core trade data: price, direction, and volume.

type Symbol added in v0.2.0

type Symbol struct {
	ID          uint       `json:"id"`                    // Unique identifier
	Type        SymbolType `json:"type"`                  // Fiat or crypto
	ParentID    uint       `json:"parentId,omitempty"`    // Parent symbol ID (0 = root)
	Code        string     `json:"code"`                  // Ticker code (e.g. "BTC", "USD")
	Name        string     `json:"name"`                  // Full name (e.g. "Bitcoin")
	Description string     `json:"description,omitempty"` // Optional description
	Website     string     `json:"website,omitempty"`     // Project/issuer website
}

Symbol represents a market trading symbol (e.g. BTC, USDT, EUR).

Symbols form a tree structure through ParentID, enabling hierarchical relationships between base assets and their derivatives:

USD  (id:1,  parent:0, fiat)
├── USDT  (id:2, parent:1, crypto)   — stablecoin pegged to USD
├── USDC  (id:3, parent:1, crypto)   — stablecoin pegged to USD
├── EUR   (id:4, parent:1, fiat)
└── GBP   (id:5, parent:1, fiat)
BTC  (id:14, parent:0, crypto)
├── BTCFT  (id:22, parent:14, crypto) — BTC futures token
└── BTCM24 (id:23, parent:14, crypto) — BTC June 2024 future

This tree allows grouping derivatives under their base asset and resolving instrument relationships across exchanges.

func (Symbol) IsCrypto added in v0.2.0

func (s Symbol) IsCrypto() bool

IsCrypto returns true if this is a cryptocurrency symbol.

func (Symbol) IsFiat added in v0.2.0

func (s Symbol) IsFiat() bool

IsFiat returns true if this is a fiat currency symbol.

func (Symbol) IsRoot added in v0.2.0

func (s Symbol) IsRoot() bool

IsRoot returns true if this symbol has no parent (top-level asset).

type SymbolType added in v0.2.0

type SymbolType int8

SymbolType classifies a trading symbol as fiat or cryptocurrency.

const (
	SymbolFiat   SymbolType = iota // Fiat currency (USD, EUR, GBP, ...)
	SymbolCrypto                   // Cryptocurrency (BTC, ETH, SOL, ...)
)

func (SymbolType) String added in v0.2.0

func (s SymbolType) String() string

String returns a human-readable label for the symbol type.

type Symbols added in v0.2.0

type Symbols []Symbol

Symbols is a collection of Symbol values with lookup helpers.

func (Symbols) Children added in v0.2.0

func (ss Symbols) Children(parentID uint) Symbols

Children returns all symbols whose ParentID matches the given ID.

func (Symbols) Cryptos added in v0.2.0

func (ss Symbols) Cryptos() Symbols

Cryptos returns all cryptocurrency symbols.

func (Symbols) Fiats added in v0.2.0

func (ss Symbols) Fiats() Symbols

Fiats returns all fiat currency symbols.

func (Symbols) GetByCode added in v0.2.0

func (ss Symbols) GetByCode(code string) *Symbol

GetByCode returns the first symbol matching the given code, or nil.

func (Symbols) GetByID added in v0.2.0

func (ss Symbols) GetByID(id uint) *Symbol

GetByID returns the symbol with the given ID, or nil.

func (Symbols) Roots added in v0.2.0

func (ss Symbols) Roots() Symbols

Roots returns all top-level symbols (ParentID == 0).

type Temperatures

type Temperatures struct {
	AskBid         AskBid `json:"askBid"`
	TimeDurationMS int64  `json:"timeDurationMs"`
	TradesCount    int64  `json:"tradesCount"`
}

Temperatures aggregates ask/bid counts with timing data.

func UnmarshalTemperatures

func UnmarshalTemperatures(data []byte) (Temperatures, error)

UnmarshalTemperatures parses JSON into a Temperatures value.

func (*Temperatures) Marshal

func (r *Temperatures) Marshal() ([]byte, error)

Marshal serializes Temperatures to JSON.

type TimeAndSale

type TimeAndSale struct {
	InternalID UUID // Internal transaction ID

	ID                 string // Exchange transaction ID / Trade ID
	ExchangeID         int64  // Exchange identifier
	DataFeedProviderID int64  // Data feed provider identifier

	TradeSequence     int64 // Sequence number for same-timestamp trades
	TradeOpenInterest int64 // Open interest at time of trade

	Ticker string    // Market trading symbol (e.g. "BTCUSDT", "ES", "NQ")
	Time   time.Time // Trade timestamp
	Sale
}

TimeAndSale represents an atomic trade transaction captured from an exchange. This is the fundamental unit of market data — each instance records a single trade event with its price, volume, aggressor side, and timing.

type UUID

type UUID struct {
	Value *uuid.UUID
}

UUID wraps uuid.UUID with custom JSON unmarshaling for string UUIDs.

func (UUID) String

func (u UUID) String() string

String returns the UUID string representation, or empty string if nil.

func (*UUID) UnmarshalJSON

func (u *UUID) UnmarshalJSON(data []byte) (err error)

UnmarshalJSON parses a JSON string into a uuid.UUID.

Directories

Path Synopsis
Package currency provides embedded fiat and cryptocurrency reference data with 170+ fiat currencies and 60+ crypto tokens, loaded from a bundled YAML file.
Package currency provides embedded fiat and cryptocurrency reference data with 170+ fiat currencies and 60+ crypto tokens, loaded from a bundled YAML file.

Jump to

Keyboard shortcuts

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