binance

package
v2.3.0 Latest Latest
Warning

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

Go to latest
Published: Jan 16, 2025 License: Apache-2.0 Imports: 12 Imported by: 0

README

Binance Provider

Overview

The Binance provider is used to fetch the ticker price from the Binance websocket API. A single connection is only valid for 24 hours; after that, a new connection must be established. The Websocket server will send a ping frame every 3 minutes. If the client does not receive a pong frame within 10 minutes, the connection will be closed. Note that all symbols are in lowercase.

The WebSocket connection has a limit of 5 incoming messages per second. A message is considered:

  • A Ping frame
  • A Pong frame
  • A JSON controlled message (e.g. a subscription)
  • A connection that goes beyond the rate limit will be disconnected. IPs that are repeatedly disconnected for going beyond the rate limit may be banned for a period of time.

A single connection can listen to a maximum of 1024 streams. If a user attempts to listen to more streams, the connection will be disconnected. There is a limit of 300 connections per attempt every 5 minutes per IP.

The specific channels / streams that are subscribed to is the Aggregate Trade Stream and the Ticker Stream. The Aggregate Trade Streams push trade information that is aggregated for a single taker order in real time. The ticker stream pushes the ticker spot price every second.

Documentation

Index

Constants

View Source
const (
	// SubscribeMethod represents a subscribe method. This must be sent as the first message
	// when connecting to the websocket feed.
	//
	// ref: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#subscribe-to-a-stream
	SubscribeMethod MethodType = "SUBSCRIBE"

	// AggregateTradeStream represents the aggregate trade stream. This stream provides
	// trade information that is aggregated for a single taker order.
	//
	// ref: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#aggregate-trade-streams
	AggregateTradeStream StreamType = "aggTrade"

	// TickerStream represents the ticker stream. This provides a 24hr rolling window ticker statistics for a single
	// symbol. These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.
	//
	// ref: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-ticker-streams
	TickerStream StreamType = "ticker"

	// Separator is the separator used to separate the instrument and the stream type.
	Separator = "@"
)

Variables

View Source
var (
	// Name is the name of the Binance exchange WebSocket provider.
	Name = "binance_ws"
	// WSS is the WSS for the Binance exchange WebSocket API.
	WSS = "wss://stream.binance.com/stream"
	// DefaultMaxSubscriptionsPerConnection is the default maximum number of subscriptions
	// per connection. By default, Binance accepts up to 1024 subscriptions per connection.
	// However, we limit this to 40 to prevent overloading the connection.
	DefaultMaxSubscriptionsPerConnection = 40
	// DefaultWriteInterval is the default write interval for the Binance exchange WebSocket.
	// Binance allows up to 5 messages to be sent per second. We set this to 300ms to
	// prevent overloading the connection.
	DefaultWriteInterval = 300 * time.Millisecond
	// DefaultHandshakeTimeout is the default handshake timeout for the Binance exchange WebSocket.
	// If we assume that for 20 markets it takes 250ms to write a message, then the handshake
	// timeout should be at least 5 seconds. We add a buffer of 5 seconds to account for network
	// latency.
	DefaultHandshakeTimeout = 20 * time.Second
)
View Source
var DefaultWebSocketConfig = config.WebSocketConfig{
	Name:                          Name,
	Enabled:                       true,
	MaxBufferSize:                 config.DefaultMaxBufferSize,
	ReconnectionTimeout:           config.DefaultReconnectionTimeout,
	PostConnectionTimeout:         config.DefaultPostConnectionTimeout,
	HandshakeTimeout:              DefaultHandshakeTimeout,
	Endpoints:                     []config.Endpoint{{URL: WSS}},
	ReadBufferSize:                config.DefaultReadBufferSize,
	WriteBufferSize:               config.DefaultWriteBufferSize,
	EnableCompression:             config.DefaultEnableCompression,
	ReadTimeout:                   config.DefaultReadTimeout,
	WriteTimeout:                  config.DefaultWriteTimeout,
	PingInterval:                  config.DefaultPingInterval,
	WriteInterval:                 DefaultWriteInterval,
	MaxReadErrorCount:             config.DefaultMaxReadErrorCount,
	MaxSubscriptionsPerConnection: DefaultMaxSubscriptionsPerConnection,
	MaxSubscriptionsPerBatch:      config.DefaultMaxSubscriptionsPerBatch,
}

DefaultWebSocketConfig is the default configuration for the Binance exchange WebSocket.

Functions

func NewWebSocketDataHandler

func NewWebSocketDataHandler(
	logger *zap.Logger,
	ws config.WebSocketConfig,
) (types.PriceWebSocketDataHandler, error)

NewWebSocketDataHandler returns a new Binance PriceWebSocketDataHandler.

Types

type AggregatedTradeMessageResponse

type AggregatedTradeMessageResponse struct {
	Data struct {
		// Ticker is the symbol.
		Ticker string `json:"s"`
		// Price is the price.
		Price string `json:"p"`
	} `json:"data"`
}

AggregatedTradeMessageResponse represents an aggregated trade message response. This is used to represent the aggregated trade data that is received from the Binance websocket.

Response

{
  	"e": "aggTrade",    // Event type
  	"E": 1672515782136, // Event time
  	"s": "BNBBTC",      // Symbol
  	"a": 12345,         // Aggregate trade ID
  	"p": "0.001",       // Price
  	"q": "100",         // Quantity
  	"f": 100,           // First trade ID
  	"l": 105,           // Last trade ID
  	"T": 1672515782136, // Trade time
  	"m": true,          // Is the buyer the market maker?
 	"M": true           // Ignore
}

ref: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#aggregate-trade-streams

type MethodType

type MethodType string

MethodType represents the type of message that is sent to the websocket feed.

type StreamMessageResponse

type StreamMessageResponse struct {
	// Stream is the stream type.
	Stream string `json:"stream"`
}

ref: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#aggregate-trade-streams

func (*StreamMessageResponse) GetStreamType

func (m *StreamMessageResponse) GetStreamType() StreamType

GetStreamType returns the stream type from the stream message response.

type StreamType

type StreamType string

StreamType represents the type of stream that is sent/received from the websocket feed. Streams are used to determine what instrument you are subscribing to / how to handle the message.

type SubscribeMessageRequest

type SubscribeMessageRequest struct {
	// Method is the method type for the message.
	Method string `json:"method"`
	// Params is the list of streams to subscribe to.
	Params []string `json:"params"`
	// ID is the unique identifier for the message.
	ID int64 `json:"id"`
}

SubscribeMessageRequest represents a subscribe message request. This is used to subscribe to Binance websocket streams.

Request

{
  "method": "SUBSCRIBE",
  "params": [
    "btcusdt@aggTrade",
    "btcusdt@depth"
  ],
  "id": 1
}

The ID field is used to uniquely identify the messages going back and forth. By default, the ID is randomly generated with a minimum value of 1.

ref: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#live-subscribingunsubscribing-to-streams

type SubscribeMessageResponse

type SubscribeMessageResponse struct {
	// Result is the result of the subscription.
	Result interface{} `json:"result"`
	// ID is the unique identifier for the message.
	ID int64 `json:"id"`
}

SubscribeMessageResponse represents a subscribe message response. This is used to determine whether the subscription was (un)successful.

Response

{
		"result": null,
		"id": 1
}

The ID field is used to uniquely identify the messages going back and forth, the same one sent in the initial subscription. The result is null if the subscription was successful.

ref: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#live-subscribingunsubscribing-to-streams

func (*SubscribeMessageResponse) IsEmpty

func (m *SubscribeMessageResponse) IsEmpty() bool

IsEmpty returns true if no data has been set for the message.

type TickerMessageResponse

type TickerMessageResponse struct {
	Data struct {
		// Ticker is the symbol.
		Ticker string `json:"s"`
		// LastPrice is the last price.
		LastPrice string `json:"c"`
		// StatisticsCloseTime is the statistics close time.
		//
		// Note: This is unused but is included since json.Unmarshal requires all fields with same character but different casing
		// to be present.
		StatisticsCloseTime int64 `json:"C"`
	} `json:"data"`
}

TickerMessageResponse represents a ticker message response. This is used to represent the ticker data that is received from the Binance websocket.

Response

{
		"e": "24hrTicker",  // Event type
		"E": 1672515782136, // Event time
		"s": "BNBBTC",      // Symbol
		"p": "0.0015",      // Price change
		"P": "250.00",      // Price change percent
		"w": "0.0018",      // Weighted average price
		"x": "0.0009",      // First trade(F)-1 price (first trade before the 24hr rolling window)
		"c": "0.0025",      // Last price
		"Q": "10",          // Last quantity
		"b": "0.0024",      // Best bid price
		"B": "10",          // Best bid quantity
		"a": "0.0026",      // Best ask price
		"A": "100",         // Best ask quantity
		"o": "0.0010",      // Open price
		"h": "0.0025",      // High price
		"l": "0.0010",      // Low price
		"v": "10000",       // Total traded base asset volume
		"q": "18",          // Total traded quote asset volume
		"O": 0,             // Statistics open time
		"C": 86400000,      // Statistics close time
		"F": 0,             // First trade ID
		"L": 18150,         // Last trade Id
		"n": 18151          // Total number of trades
}

ref: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-ticker-streams

type WebSocketHandler

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

WebSocketHandler implements the WebSocketDataHandler interface. This is used to handle messages received from the Binance websocket API.

func (*WebSocketHandler) Copy

Copy is used to create a copy of the WebSocketHandler.

func (*WebSocketHandler) CreateMessages

func (h *WebSocketHandler) CreateMessages(
	tickers []types.ProviderTicker,
) ([]handlers.WebsocketEncodedMessage, error)

CreateMessages is used to create a message to send to Binance. This is used to subscribe to the given tickers. This is called when the connection to the data provider is first established. Notably, the tickers have a unique identifier that is used to identify the messages going back and forth. This unique identifier is the same one sent in the initial subscription.

func (*WebSocketHandler) GenerateID

func (h *WebSocketHandler) GenerateID() int64

GenerateID generates a random ID for the message.

func (*WebSocketHandler) HandleMessage

func (h *WebSocketHandler) HandleMessage(
	message []byte,
) (types.PriceResponse, []handlers.WebsocketEncodedMessage, error)

HandleMessage is used to handle a message received from the data provider. The Binance websocket API is expected to handle the following types of messages:

  1. SubscribeMessageResponse: This is a response to a subscription request. If the subscription was successful, the response will contain a nil result. If the subscription failed, a re-subscription message will be returned.
  2. StreamMessageResponse: This is a response to a stream message. The stream message contains the latest price of a ticker - either received when a trade is made or an automated price update is received.

Heartbeat messages are handled by default by the gorilla websocket library. The Binance websocket API does not require any additional heartbeat messages to be sent. The pong frames are sent automatically by the gorilla websocket library.

func (*WebSocketHandler) HeartBeatMessages

func (h *WebSocketHandler) HeartBeatMessages() ([]handlers.WebsocketEncodedMessage, error)

HeartBeatMessages is not used for Binance. Heartbeats are handled on an ad-hoc basis when messages are received from the Binance websocket API.

ref: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#aggregate-trade-streams

func (*WebSocketHandler) NewSubscribeRequestMessage

func (h *WebSocketHandler) NewSubscribeRequestMessage(instruments []string) ([]handlers.WebsocketEncodedMessage, error)

NewSubscribeRequestMessage returns a set of messages to subscribe to the Binance websocket. This will subscribe each instrument to the aggregate trade and ticker streams.

func (*WebSocketHandler) SetIDForInstruments

func (h *WebSocketHandler) SetIDForInstruments(id int64, instruments []string)

SetIDForInstruments sets the ID for the given instruments. This is used to set the ID for the instruments that are being subscribed to.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
JackTT - Gopher 🇻🇳