mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-02 15:10:46 +00:00
Merge branch 'master' into engine
This commit is contained in:
@@ -1,15 +1,18 @@
|
||||
package bitfinex
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/sharedtestvalues"
|
||||
)
|
||||
|
||||
// Please supply your own keys here to do better tests
|
||||
@@ -38,6 +41,7 @@ func TestSetup(t *testing.T) {
|
||||
}
|
||||
|
||||
b.API.AuthenticatedSupport = true
|
||||
b.API.AuthenticatedWebsocketSupport = true
|
||||
// custom rate limit for testing
|
||||
b.Requester.SetRateLimit(true, time.Millisecond*300, 1)
|
||||
b.Requester.SetRateLimit(false, time.Millisecond*300, 1)
|
||||
@@ -962,3 +966,37 @@ func TestGetDepositAddress(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestWsAuth dials websocket, sends login request.
|
||||
func TestWsAuth(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport || !areTestAPIKeysSet() {
|
||||
t.Skip(exchange.WebsocketNotEnabled)
|
||||
}
|
||||
var err error
|
||||
var dialer websocket.Dialer
|
||||
b.WebsocketConn, _, err = dialer.Dial(b.Websocket.GetWebsocketURL(),
|
||||
http.Header{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride()
|
||||
b.Websocket.TrafficAlert = sharedtestvalues.GetWebsocketStructChannelOverride()
|
||||
go b.WsDataHandler()
|
||||
defer b.WebsocketConn.Close()
|
||||
err = b.WsSendAuth()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
|
||||
select {
|
||||
case resp := <-b.Websocket.DataHandler:
|
||||
if resp.(map[string]interface{})["event"] != "auth" && resp.(map[string]interface{})["status"] != "OK" {
|
||||
t.Error("expected successful login")
|
||||
}
|
||||
case <-timer.C:
|
||||
t.Error("Have not received a response")
|
||||
}
|
||||
timer.Stop()
|
||||
}
|
||||
|
||||
@@ -448,6 +448,18 @@ type WebsocketTradeExecuted struct {
|
||||
PriceExecuted float64
|
||||
}
|
||||
|
||||
// WebsocketTradeData holds executed trade data
|
||||
type WebsocketTradeData struct {
|
||||
TradeID int64
|
||||
Pair string
|
||||
Timestamp int64
|
||||
OrderID int64
|
||||
AmountExecuted float64
|
||||
PriceExecuted float64
|
||||
Fee float64
|
||||
FeeCurrency string
|
||||
}
|
||||
|
||||
// ErrorCapture is a simple type for returned errors from Bitfinex
|
||||
type ErrorCapture struct {
|
||||
Message string `json:"message"`
|
||||
|
||||
@@ -20,28 +20,30 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
bitfinexWebsocket = "wss://api.bitfinex.com/ws"
|
||||
bitfinexWebsocketVersion = "1.1"
|
||||
bitfinexWebsocketPositionSnapshot = "ps"
|
||||
bitfinexWebsocketPositionNew = "pn"
|
||||
bitfinexWebsocketPositionUpdate = "pu"
|
||||
bitfinexWebsocketPositionClose = "pc"
|
||||
bitfinexWebsocketWalletSnapshot = "ws"
|
||||
bitfinexWebsocketWalletUpdate = "wu"
|
||||
bitfinexWebsocketOrderSnapshot = "os"
|
||||
bitfinexWebsocketOrderNew = "on"
|
||||
bitfinexWebsocketOrderUpdate = "ou"
|
||||
bitfinexWebsocketOrderCancel = "oc"
|
||||
bitfinexWebsocketTradeExecuted = "te"
|
||||
bitfinexWebsocketHeartbeat = "hb"
|
||||
bitfinexWebsocketAlertRestarting = "20051"
|
||||
bitfinexWebsocketAlertRefreshing = "20060"
|
||||
bitfinexWebsocketAlertResume = "20061"
|
||||
bitfinexWebsocketUnknownEvent = "10000"
|
||||
bitfinexWebsocketUnknownPair = "10001"
|
||||
bitfinexWebsocketSubscriptionFailed = "10300"
|
||||
bitfinexWebsocketAlreadySubscribed = "10301"
|
||||
bitfinexWebsocketUnknownChannel = "10302"
|
||||
bitfinexWebsocket = "wss://api.bitfinex.com/ws"
|
||||
bitfinexWebsocketVersion = "1.1"
|
||||
bitfinexWebsocketPositionSnapshot = "ps"
|
||||
bitfinexWebsocketPositionNew = "pn"
|
||||
bitfinexWebsocketPositionUpdate = "pu"
|
||||
bitfinexWebsocketPositionClose = "pc"
|
||||
bitfinexWebsocketWalletSnapshot = "ws"
|
||||
bitfinexWebsocketWalletUpdate = "wu"
|
||||
bitfinexWebsocketOrderSnapshot = "os"
|
||||
bitfinexWebsocketOrderNew = "on"
|
||||
bitfinexWebsocketOrderUpdate = "ou"
|
||||
bitfinexWebsocketOrderCancel = "oc"
|
||||
bitfinexWebsocketTradeExecuted = "te"
|
||||
bitfinexWebsocketTradeExecutionUpdate = "tu"
|
||||
bitfinexWebsocketTradeSnapshots = "ts"
|
||||
bitfinexWebsocketHeartbeat = "hb"
|
||||
bitfinexWebsocketAlertRestarting = "20051"
|
||||
bitfinexWebsocketAlertRefreshing = "20060"
|
||||
bitfinexWebsocketAlertResume = "20061"
|
||||
bitfinexWebsocketUnknownEvent = "10000"
|
||||
bitfinexWebsocketUnknownPair = "10001"
|
||||
bitfinexWebsocketSubscriptionFailed = "10300"
|
||||
bitfinexWebsocketAlreadySubscribed = "10301"
|
||||
bitfinexWebsocketUnknownChannel = "10302"
|
||||
)
|
||||
|
||||
// WebsocketHandshake defines the communication between the websocket API for
|
||||
@@ -78,6 +80,9 @@ func (b *Bitfinex) wsSend(data interface{}) error {
|
||||
|
||||
// WsSendAuth sends a autheticated event payload
|
||||
func (b *Bitfinex) WsSendAuth() error {
|
||||
if !b.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
|
||||
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", b.Name)
|
||||
}
|
||||
req := make(map[string]interface{})
|
||||
payload := "AUTH" + strconv.FormatInt(time.Now().UnixNano(), 10)[:13]
|
||||
req["event"] = "auth"
|
||||
@@ -91,7 +96,12 @@ func (b *Bitfinex) WsSendAuth() error {
|
||||
|
||||
req["authPayload"] = payload
|
||||
|
||||
return b.wsSend(req)
|
||||
err := b.wsSend(req)
|
||||
if err != nil {
|
||||
b.Websocket.SetCanUseAuthenticatedEndpoints(false)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WsSendUnauth sends an unauthenticated payload
|
||||
@@ -151,6 +161,11 @@ func (b *Bitfinex) WsConnect() error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = b.WsSendAuth()
|
||||
if err != nil {
|
||||
log.Errorf("%v - authentication failed: %v", b.Name, err)
|
||||
}
|
||||
|
||||
b.GenerateDefaultSubscriptions()
|
||||
if hs.Event == "info" {
|
||||
if b.Verbose {
|
||||
@@ -158,13 +173,6 @@ func (b *Bitfinex) WsConnect() error {
|
||||
}
|
||||
}
|
||||
|
||||
if b.AllowAuthenticatedRequest() {
|
||||
err = b.WsSendAuth()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
pongReceive = make(chan struct{}, 1)
|
||||
|
||||
go b.WsDataHandler()
|
||||
@@ -226,15 +234,13 @@ func (b *Bitfinex) WsDataHandler() {
|
||||
|
||||
case "auth":
|
||||
status := eventData["status"].(string)
|
||||
|
||||
if status == "OK" {
|
||||
b.Websocket.DataHandler <- eventData
|
||||
b.WsAddSubscriptionChannel(0, "account", "N/A")
|
||||
|
||||
} else if status == "fail" {
|
||||
b.Websocket.DataHandler <- fmt.Errorf("bitfinex.go error - Websocket unable to AUTH. Error code: %s",
|
||||
eventData["code"].(string))
|
||||
|
||||
b.API.AuthenticatedSupport = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,6 +424,19 @@ func (b *Bitfinex) WsDataHandler() {
|
||||
AmountExecuted: data[4].(float64),
|
||||
PriceExecuted: data[5].(float64)}
|
||||
|
||||
b.Websocket.DataHandler <- trade
|
||||
case bitfinexWebsocketTradeSnapshots, bitfinexWebsocketTradeExecutionUpdate:
|
||||
data := chanData[2].([]interface{})
|
||||
trade := WebsocketTradeData{
|
||||
TradeID: int64(data[0].(float64)),
|
||||
Pair: data[1].(string),
|
||||
Timestamp: int64(data[2].(float64)),
|
||||
OrderID: int64(data[3].(float64)),
|
||||
AmountExecuted: data[4].(float64),
|
||||
PriceExecuted: data[5].(float64),
|
||||
Fee: data[6].(float64),
|
||||
FeeCurrency: data[7].(string)}
|
||||
|
||||
b.Websocket.DataHandler <- trade
|
||||
}
|
||||
|
||||
@@ -603,7 +622,7 @@ func (b *Bitfinex) WsUpdateOrderbook(p currency.Pair, assetType asset.Item, book
|
||||
// GenerateDefaultSubscriptions Adds default subscriptions to websocket to be handled by ManageSubscriptions()
|
||||
func (b *Bitfinex) GenerateDefaultSubscriptions() {
|
||||
var channels = []string{"book", "trades", "ticker"}
|
||||
subscriptions := []exchange.WebsocketChannelSubscription{}
|
||||
var subscriptions []exchange.WebsocketChannelSubscription
|
||||
for i := range channels {
|
||||
enabledPairs := b.GetEnabledPairs(asset.Spot)
|
||||
for j := range enabledPairs {
|
||||
@@ -626,7 +645,9 @@ func (b *Bitfinex) Subscribe(channelToSubscribe exchange.WebsocketChannelSubscri
|
||||
req := make(map[string]interface{})
|
||||
req["event"] = "subscribe"
|
||||
req["channel"] = channelToSubscribe.Channel
|
||||
req["pair"] = channelToSubscribe.Currency.String()
|
||||
if channelToSubscribe.Currency.String() != "" {
|
||||
req["pair"] = channelToSubscribe.Currency.String()
|
||||
}
|
||||
if len(channelToSubscribe.Params) > 0 {
|
||||
for k, v := range channelToSubscribe.Params {
|
||||
req[k] = v
|
||||
|
||||
@@ -579,3 +579,13 @@ func (b *Bitfinex) UnsubscribeToWebsocketChannels(channels []exchange.WebsocketC
|
||||
b.Websocket.UnsubscribeToChannels(channels)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSubscriptions returns a copied list of subscriptions
|
||||
func (b *Bitfinex) GetSubscriptions() ([]exchange.WebsocketChannelSubscription, error) {
|
||||
return b.Websocket.GetSubscriptions(), nil
|
||||
}
|
||||
|
||||
// AuthenticateWebsocket sends an authentication message to the websocket
|
||||
func (b *Bitfinex) AuthenticateWebsocket() error {
|
||||
return b.WsSendAuth()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user