mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
Binance websocket (#143)
* optimize dockerfile to not invalidate layers * added binance websocket * added binance websocket types * loading exchanges from the codebase * Setting Binance websocket to Yes * revert import naming * binance websocket was missing * added gorilla websocket
This commit is contained in:
committed by
Adrian Gallagher
parent
4fadc6ff48
commit
42ea6ba598
@@ -1,13 +1,16 @@
|
||||
FROM golang:1.9.4 as build
|
||||
WORKDIR /go/src/github.com/thrasher-/gocryptotrader
|
||||
RUN curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||
WORKDIR /go/src/gocryptotrader
|
||||
COPY Gopkg.* ./
|
||||
RUN dep ensure -vendor-only
|
||||
COPY . .
|
||||
RUN mv -vn config_example.json config.json \
|
||||
&& go get -v -d \
|
||||
&& GOARCH=386 GOOS=linux CGO_ENABLED=0 go install -v \
|
||||
&& mv /go/bin/linux_386 /go/bin/gocryptotrader
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk update && apk add --no-cache ca-certificates
|
||||
COPY --from=build /go/bin/gocryptotrader /app/
|
||||
COPY --from=build /go/src/github.com/thrasher-/gocryptotrader/config.json /app/
|
||||
COPY --from=build /go/src/gocryptotrader/config.json /app/
|
||||
EXPOSE 9050
|
||||
CMD ["/app/gocryptotrader"]
|
||||
|
||||
@@ -20,7 +20,7 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader
|
||||
|----------|------|-----------|-----|
|
||||
| Alphapoint | Yes | Yes | NA |
|
||||
| ANXPRO | Yes | No | NA |
|
||||
| Binance| Yes | No | NA |
|
||||
| Binance| Yes | Yes | NA |
|
||||
| Bitfinex | Yes | Yes | NA |
|
||||
| Bitflyer | Yes | No | NA |
|
||||
| Bithumb | Yes | NA | NA |
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
// Binance is the overarching type across the Bithumb package
|
||||
type Binance struct {
|
||||
exchange.Base
|
||||
WebsocketConn *websocket.Conn
|
||||
|
||||
// valid string list that a required by the exchange
|
||||
validLimits []string
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package binance
|
||||
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Response holds basic binance api response data
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
@@ -75,6 +80,75 @@ type RecentTrade struct {
|
||||
IsBestMatch bool `json:"isBestMatch"`
|
||||
}
|
||||
|
||||
type MultiStreamData struct {
|
||||
Stream string `json:"stream"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
}
|
||||
|
||||
type TradeStream struct {
|
||||
EventType string `json:"e"`
|
||||
EventTime int64 `json:"E"`
|
||||
Symbol string `json:"s"`
|
||||
TradeID int64 `json:"t"`
|
||||
Price string `json:"p"`
|
||||
Quantity string `json:"q"`
|
||||
BuyerOrderID int64 `json:"b"`
|
||||
SellerOrderID int64 `json:"a"`
|
||||
TimeStamp int64 `json:"T"`
|
||||
Maker bool `json:"m"`
|
||||
BestMatchPrice bool `json:"M"`
|
||||
}
|
||||
|
||||
type KlineStream struct {
|
||||
EventType string `json:"e"`
|
||||
EventTime int64 `json:"E"`
|
||||
Symbol string `json:"s"`
|
||||
Kline struct {
|
||||
StartTime int64 `json:"t"`
|
||||
CloseTime int64 `json:"T"`
|
||||
Symbol string `json:"s"`
|
||||
Interval string `json:"i"`
|
||||
FirstTradeID int64 `json:"f"`
|
||||
LastTradeID int64 `json:"L"`
|
||||
OpenPrice string `json:"o"`
|
||||
ClosePrice string `json:"c"`
|
||||
HighPrice string `json:"h"`
|
||||
LowPrice string `json:"l"`
|
||||
Volume string `json:"v"`
|
||||
NumberOfTrades int64 `json:"n"`
|
||||
KlineClosed bool `json:"x"`
|
||||
Quote string `json:"q"`
|
||||
TakerBuyBaseAssetVolume string `json:"V"`
|
||||
TakerBuyQuoteAssetVolume string `json:"Q"`
|
||||
} `json:"k"`
|
||||
}
|
||||
|
||||
type TickerStream struct {
|
||||
EventType string `json:"e"`
|
||||
EventTime int64 `json:"E"`
|
||||
Symbol string `json:"s"`
|
||||
PriceChange string `json:"p"`
|
||||
PriceChangePercent string `json:"P"`
|
||||
WeightedAvgPrice string `json:"w"`
|
||||
PrevDayClose string `json:"x"`
|
||||
CurrDayClose string `json:"c"`
|
||||
CloseTradeQuantity string `json:"Q"`
|
||||
BestBidPrice string `json:"b"`
|
||||
BestBidQuantity string `json:"B"`
|
||||
BestAskPrice string `json:"a"`
|
||||
BestAskQuantity string `json:"A"`
|
||||
OpenPrice string `json:"o"`
|
||||
HighPrice string `json:"h"`
|
||||
LowPrice string `json:"l"`
|
||||
TotalTradedVolume string `json:"v"`
|
||||
TotalTradedQuoteVolume string `json:"q"`
|
||||
OpenTime int64 `json:"O"`
|
||||
CloseTime int64 `json:"C"`
|
||||
FirstTradeID int64 `json:"F"`
|
||||
LastTradeID int64 `json:"L"`
|
||||
NumberOfTrades int64 `json:"n"`
|
||||
}
|
||||
|
||||
// HistoricalTrade holds recent trade data
|
||||
type HistoricalTrade struct {
|
||||
Code int `json:"code"`
|
||||
|
||||
97
exchanges/binance/binance_websocket.go
Normal file
97
exchanges/binance/binance_websocket.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package binance
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
const (
|
||||
binanceDefaultWebsocketURL = "wss://stream.binance.com:9443"
|
||||
binancePingPeriod = 20 * time.Second
|
||||
)
|
||||
|
||||
func (b *Binance) WebsocketClient() {
|
||||
for b.Enabled && b.Websocket {
|
||||
var Dialer websocket.Dialer
|
||||
var err error
|
||||
// myenabledPairs := strings.ToLower(strings.Replace(strings.Join(b.EnabledPairs, "@ticker/"), "-", "", -1)) + "@trade"
|
||||
|
||||
myenabledPairsTicker := strings.ToLower(strings.Replace(strings.Join(b.EnabledPairs, "@ticker/"), "-", "", -1)) + "@ticker"
|
||||
myenabledPairsTrade := strings.ToLower(strings.Replace(strings.Join(b.EnabledPairs, "@trade/"), "-", "", -1)) + "@trade"
|
||||
myenabledPairsKline := strings.ToLower(strings.Replace(strings.Join(b.EnabledPairs, "@kline_1m/"), "-", "", -1)) + "@kline_1m"
|
||||
wsurl := b.WebsocketURL + "/stream?streams=" + myenabledPairsTicker + "/" + myenabledPairsTrade + "/" + myenabledPairsKline
|
||||
|
||||
// b.WebsocketConn, _, err = Dialer.Dial(binanceDefaultWebsocketURL+myenabledPairs, http.Header{})
|
||||
b.WebsocketConn, _, err = Dialer.Dial(wsurl, http.Header{})
|
||||
|
||||
if err != nil {
|
||||
log.Printf("%s Unable to connect to Websocket. Error: %s\n", b.Name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if b.Verbose {
|
||||
log.Printf("%s Connected to Websocket.\n", b.Name)
|
||||
}
|
||||
|
||||
for b.Enabled && b.Websocket {
|
||||
msgType, resp, err := b.WebsocketConn.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
break
|
||||
}
|
||||
|
||||
switch msgType {
|
||||
case websocket.TextMessage:
|
||||
multiStreamData := MultiStreamData{}
|
||||
|
||||
err := common.JSONDecode(resp, &multiStreamData)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Could not load multi stream data.", string(resp))
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.Contains(multiStreamData.Stream, "trade") {
|
||||
trade := TradeStream{}
|
||||
err := common.JSONDecode(multiStreamData.Data, &trade)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Could not convert to a TradeStream structure")
|
||||
continue
|
||||
}
|
||||
log.Println("Trade received", trade.Symbol, trade.TimeStamp, trade.TradeID, trade.Price, trade.Quantity)
|
||||
} else if strings.Contains(multiStreamData.Stream, "ticker") {
|
||||
ticker := TickerStream{}
|
||||
|
||||
err := common.JSONDecode(multiStreamData.Data, &ticker)
|
||||
if err != nil {
|
||||
log.Println("Could not convert to a TickerStream structure")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Println("Ticker received", ticker.Symbol, ticker.EventTime, ticker.TotalTradedVolume, ticker.LastTradeID)
|
||||
} else if strings.Contains(multiStreamData.Stream, "kline") {
|
||||
kline := KlineStream{}
|
||||
|
||||
err := common.JSONDecode(multiStreamData.Data, &kline)
|
||||
if err != nil {
|
||||
log.Println("Could not convert to a KlineStream structure")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Println("Kline received", kline.Symbol, kline.EventTime, kline.Kline.HighPrice, kline.Kline.LowPrice)
|
||||
}
|
||||
type MsgType struct {
|
||||
MessageType string `json:"messageType"`
|
||||
}
|
||||
}
|
||||
}
|
||||
b.WebsocketConn.Close()
|
||||
log.Printf("%s Websocket client disconnected.", b.Name)
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,10 @@ func (b *Binance) Run() {
|
||||
log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs)
|
||||
}
|
||||
|
||||
if b.Websocket {
|
||||
go b.WebsocketClient()
|
||||
}
|
||||
|
||||
symbols, err := b.GetExchangeValidCurrencyPairs()
|
||||
if err != nil {
|
||||
log.Printf("%s Failed to get exchange info.\n", b.GetName())
|
||||
|
||||
Reference in New Issue
Block a user