Skip to content

Commit

Permalink
Binance websocket (thrasher-corp#143)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
ermalguni authored and thrasher- committed Jul 16, 2018
1 parent 4fadc6f commit 42ea6ba
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 4 deletions.
9 changes: 6 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
2 changes: 2 additions & 0 deletions exchanges/binance/binance.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down
74 changes: 74 additions & 0 deletions exchanges/binance/binance_types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package binance


import (
"encoding/json"
)

// Response holds basic binance api response data
type Response struct {
Code int `json:"code"`
Expand Down Expand Up @@ -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"`
Expand Down
97 changes: 97 additions & 0 deletions exchanges/binance/binance_websocket.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
4 changes: 4 additions & 0 deletions exchanges/binance/binance_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down

0 comments on commit 42ea6ba

Please sign in to comment.