Merge branch 'master' into engine

This commit is contained in:
Adrian Gallagher
2019-08-09 15:46:24 +10:00
353 changed files with 4966 additions and 4196 deletions

View File

@@ -1,13 +1,13 @@
# GoCryptoTrader package Zb
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/page-logo.png?raw=true" width="350px" height="350px" hspace="70">
<img src="https://github.com/thrasher-corp/gocryptotrader/blob/master/web/src/assets/page-logo.png?raw=true" width="350px" height="350px" hspace="70">
[![Build Status](https://travis-ci.org/thrasher-/gocryptotrader.svg?branch=master)](https://travis-ci.org/thrasher-/gocryptotrader)
[![Software License](https://img.shields.io/badge/License-MIT-orange.svg?style=flat-square)](https://github.com/thrasher-/gocryptotrader/blob/master/LICENSE)
[![GoDoc](https://godoc.org/github.com/thrasher-/gocryptotrader?status.svg)](https://godoc.org/github.com/thrasher-/gocryptotrader/exchanges/zb)
[![Coverage Status](http://codecov.io/github/thrasher-/gocryptotrader/coverage.svg?branch=master)](http://codecov.io/github/thrasher-/gocryptotrader?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/thrasher-/gocryptotrader)](https://goreportcard.com/report/github.com/thrasher-/gocryptotrader)
[![Build Status](https://travis-ci.org/thrasher-corp/gocryptotrader.svg?branch=master)](https://travis-ci.org/thrasher-corp/gocryptotrader)
[![Software License](https://img.shields.io/badge/License-MIT-orange.svg?style=flat-square)](https://github.com/thrasher-corp/gocryptotrader/blob/master/LICENSE)
[![GoDoc](https://godoc.org/github.com/thrasher-corp/gocryptotrader?status.svg)](https://godoc.org/github.com/thrasher-corp/gocryptotrader/exchanges/zb)
[![Coverage Status](http://codecov.io/github/thrasher-corp/gocryptotrader/coverage.svg?branch=master)](http://codecov.io/github/thrasher-corp/gocryptotrader?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/thrasher-corp/gocryptotrader)](https://goreportcard.com/report/github.com/thrasher-corp/gocryptotrader)
This zb package is part of the GoCryptoTrader codebase.
@@ -26,7 +26,7 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader
### How to enable
+ [Enable via configuration](https://github.com/thrasher-/gocryptotrader/tree/master/config#enable-exchange-via-config-example)
+ [Enable via configuration](https://github.com/thrasher-corp/gocryptotrader/tree/master/config#enable-exchange-via-config-example)
+ Individual package example below:
@@ -127,12 +127,12 @@ When submitting a PR, please abide by our coding guidelines:
+ Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)).
+ Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines.
+ Code must adhere to our [coding style](https://github.com/thrasher-/gocryptotrader/blob/master/doc/coding_style.md).
+ Code must adhere to our [coding style](https://github.com/thrasher-corp/gocryptotrader/blob/master/doc/coding_style.md).
+ Pull requests need to be based on and opened against the `master` branch.
## Donations
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/donate.png?raw=true" hspace="70">
<img src="https://github.com/thrasher-corp/gocryptotrader/blob/master/web/src/assets/donate.png?raw=true" hspace="70">
If this framework helped you in any way, or you would like to support the developers working on it, please donate Bitcoin to:

View File

@@ -8,15 +8,14 @@ import (
"net/url"
"strconv"
"strings"
"sync"
"time"
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/common/convert"
"github.com/thrasher-/gocryptotrader/common/crypto"
"github.com/thrasher-/gocryptotrader/currency"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/common/convert"
"github.com/thrasher-corp/gocryptotrader/common/crypto"
"github.com/thrasher-corp/gocryptotrader/currency"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/wshandler"
)
const (
@@ -45,9 +44,8 @@ const (
// 47.91.169.147 api.zb.com
// 47.52.55.212 trade.zb.com
type ZB struct {
WebsocketConn *websocket.Conn
WebsocketConn *wshandler.WebsocketConnection
exchange.Base
wsRequestMtx sync.Mutex
}
// SpotNewOrder submits an order to ZB

View File

@@ -4,14 +4,13 @@ import (
"fmt"
"net/http"
"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"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/currency"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/wshandler"
)
// Please supply you own test keys here for due diligence testing.
@@ -50,12 +49,17 @@ func setupWsAuth(t *testing.T) {
z.SetDefaults()
TestSetup(t)
if !z.Websocket.IsEnabled() && !z.API.AuthenticatedWebsocketSupport || !areTestAPIKeysSet() || !canManipulateRealOrders {
t.Skip(exchange.WebsocketNotEnabled)
t.Skip(wshandler.WebsocketNotEnabled)
}
z.WebsocketConn = &wshandler.WebsocketConnection{
ExchangeName: z.Name,
URL: zbWebsocketAPI,
Verbose: z.Verbose,
ResponseMaxLimit: exchange.DefaultWebsocketResponseMaxLimit,
ResponseCheckTimeout: exchange.DefaultWebsocketResponseCheckTimeout,
}
var err error
var dialer websocket.Dialer
z.WebsocketConn, _, err = dialer.Dial(z.Websocket.GetWebsocketURL(),
http.Header{})
err := z.WebsocketConn.Dial(&dialer, http.Header{})
if err != nil {
t.Fatal(err)
}
@@ -499,224 +503,116 @@ func TestZBInvalidJSON(t *testing.T) {
var response WsGetSubUserListResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
t.Log(err)
t.Fatal(err)
}
if response.Message[0].UserID != 1337 {
t.Error("Expected extracted JSON USERID to equal 1337")
t.Fatal("Expected extracted JSON USERID to equal 1337")
}
json = `{"success":true,"code":1000,"channel":"createSubUserKey","message":"{"apiKey":"thisisnotareallykeyyousillybilly","apiSecret":"lol"}","no":"14728151154382111746154"}`
json = `{"success":true,"code":1000,"channel":"createSubUserKey","message":"{"apiKey":"thisisnotareallykeyyousillybilly","apiSecret":"lol"}","no":"123"}`
fixedJSON = z.wsFixInvalidJSON([]byte(json))
var response2 WsRequestResponse
err = common.JSONDecode(fixedJSON, &response2)
if err != nil {
t.Log(err)
t.Error(err)
}
}
// TestWsTransferFunds ws test
func TestWsTransferFunds(t *testing.T) {
setupWsAuth(t)
err := z.wsDoTransferFunds(currency.BTC,
_, err := z.wsDoTransferFunds(currency.BTC,
0.0001,
"username1",
"username2",
)
if err != nil {
t.Error(err)
t.Fatal(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsRequestResponse).Code == 1002 || resp.(WsRequestResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
}
timer.Stop()
}
// TestWsCreateSuUserKey ws test
func TestWsCreateSuUserKey(t *testing.T) {
setupWsAuth(t)
z.wsGetSubUserList()
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
var userID int64
select {
case resp := <-z.Websocket.DataHandler:
if len(resp.(WsGetSubUserListResponse).Message) == 0 {
t.Fatal("Expected a userID. Ensure you have made a subuserID before running this test")
}
userID = resp.(WsGetSubUserListResponse).Message[0].UserID
case <-timer.C:
t.Fatal("Have not received a response")
}
timer.Stop()
err := z.wsCreateSubUserKey(true, true, true, true, "subu", fmt.Sprintf("%v", userID))
subUsers, err := z.wsGetSubUserList()
if err != nil {
t.Error(err)
t.Fatal(err)
}
timer = time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsRequestResponse).Code == 1002 || resp.(WsRequestResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
userID := subUsers.Message[0].UserID
_, err = z.wsCreateSubUserKey(true, true, true, true, "subu", fmt.Sprintf("%v", userID))
if err != nil {
t.Fatal(err)
}
timer.Stop()
}
// TestGetSubUserList ws test
func TestGetSubUserList(t *testing.T) {
setupWsAuth(t)
err := z.wsGetSubUserList()
_, err := z.wsGetSubUserList()
if err != nil {
t.Fatal(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsGetSubUserListResponse).Code == 1002 || resp.(WsGetSubUserListResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
}
timer.Stop()
}
// TestAddSubUser ws test
func TestAddSubUser(t *testing.T) {
setupWsAuth(t)
err := z.wsAddSubUser("abcde", "123456789101112aA!")
_, err := z.wsAddSubUser("1", "123456789101112aA!")
if err != nil {
t.Fatal(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsRequestResponse).Code == 1002 || resp.(WsRequestResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
}
timer.Stop()
}
// TestWsSubmitOrder ws test
func TestWsSubmitOrder(t *testing.T) {
setupWsAuth(t)
err := z.wsSubmitOrder(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1, 1, 1)
_, err := z.wsSubmitOrder(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1, 1, 1)
if err != nil {
t.Fatal(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsSubmitOrderResponse).Code == 1002 || resp.(WsSubmitOrderResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
}
timer.Stop()
}
// TestWsCancelOrder ws test
func TestWsCancelOrder(t *testing.T) {
setupWsAuth(t)
err := z.wsCancelOrder(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1234)
_, err := z.wsCancelOrder(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1234)
if err != nil {
t.Fatal(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsCancelOrderResponse).Code == 1002 || resp.(WsCancelOrderResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
}
timer.Stop()
}
// TestWsGetAccountInfo ws test
func TestWsGetAccountInfo(t *testing.T) {
setupWsAuth(t)
err := z.wsGetAccountInfoRequest()
_, err := z.wsGetAccountInfoRequest()
if err != nil {
t.Fatal(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsGetAccountInfoResponse).Code == 1002 || resp.(WsGetAccountInfoResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
}
timer.Stop()
}
// TestWsGetOrder ws test
func TestWsGetOrder(t *testing.T) {
setupWsAuth(t)
err := z.wsGetOrder(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1234)
_, err := z.wsGetOrder(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1234)
if err != nil {
t.Fatal(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsGetOrderResponse).Code == 1002 || resp.(WsGetOrderResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
}
timer.Stop()
}
// TestWsGetOrders ws test
func TestWsGetOrders(t *testing.T) {
setupWsAuth(t)
err := z.wsGetOrders(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1, 1)
_, err := z.wsGetOrders(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1, 1)
if err != nil {
t.Fatal(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsGetOrdersResponse).Code == 1002 || resp.(WsGetOrdersResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
}
timer.Stop()
}
// TestWsGetOrdersIgnoreTradeType ws test
func TestWsGetOrdersIgnoreTradeType(t *testing.T) {
setupWsAuth(t)
err := z.wsGetOrdersIgnoreTradeType(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1, 1)
_, err := z.wsGetOrdersIgnoreTradeType(currency.NewPairWithDelimiter(currency.LTC.String(), currency.BTC.String(), "").Lower(), 1, 1)
if err != nil {
t.Fatal(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resp := <-z.Websocket.DataHandler:
if resp.(WsGetOrdersResponse).Code == 1002 || resp.(WsGetOrdersResponse).Code == 1003 {
t.Error("Hash not calculated correctly")
}
case <-timer.C:
t.Error("Have not received a response")
}
timer.Stop()
}

View File

@@ -3,8 +3,8 @@ package zb
import (
"time"
"github.com/thrasher-/gocryptotrader/currency"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/currency"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
)
// OrderbookResponse holds the orderbook data for a symbol

View File

@@ -4,45 +4,34 @@ import (
"errors"
"fmt"
"net/http"
"net/url"
"regexp"
"strings"
"time"
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/common/crypto"
"github.com/thrasher-/gocryptotrader/currency"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/asset"
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
log "github.com/thrasher-/gocryptotrader/logger"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/common/crypto"
"github.com/thrasher-corp/gocryptotrader/currency"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/wshandler"
log "github.com/thrasher-corp/gocryptotrader/logger"
)
const (
zbWebsocketAPI = "wss://api.zb.cn:9999/websocket"
zWebsocketAddChannel = "addChannel"
zbWebsocketRateLimit = 20
)
// WsConnect initiates a websocket connection
func (z *ZB) WsConnect() error {
if !z.Websocket.IsEnabled() || !z.IsEnabled() {
return errors.New(exchange.WebsocketNotEnabled)
return errors.New(wshandler.WebsocketNotEnabled)
}
var dialer websocket.Dialer
if z.Websocket.GetProxyAddress() != "" {
proxy, err := url.Parse(z.Websocket.GetProxyAddress())
if err != nil {
return err
}
dialer.Proxy = http.ProxyURL(proxy)
}
var err error
z.WebsocketConn, _, err = dialer.Dial(z.Websocket.GetWebsocketURL(),
http.Header{})
err := z.WebsocketConn.Dial(&dialer, http.Header{})
if err != nil {
return err
}
@@ -53,18 +42,6 @@ func (z *ZB) WsConnect() error {
return nil
}
// WsReadData reads from the websocket connection and returns the websocket
// response
func (z *ZB) WsReadData() (exchange.WebsocketResponse, error) {
_, resp, err := z.WebsocketConn.ReadMessage()
if err != nil {
return exchange.WebsocketResponse{}, err
}
z.Websocket.TrafficAlert <- struct{}{}
return exchange.WebsocketResponse{Raw: resp}, nil
}
// WsHandleData handles all the websocket data coming from the websocket
// connection
func (z *ZB) WsHandleData() {
@@ -79,12 +56,12 @@ func (z *ZB) WsHandleData() {
case <-z.Websocket.ShutdownC:
return
default:
resp, err := z.WsReadData()
resp, err := z.WebsocketConn.ReadMessage()
if err != nil {
z.Websocket.DataHandler <- err
time.Sleep(time.Second)
continue
return
}
z.Websocket.TrafficAlert <- struct{}{}
fixedJSON := z.wsFixInvalidJSON(resp.Raw)
var result Generic
err = common.JSONDecode(fixedJSON, &result)
@@ -92,13 +69,16 @@ func (z *ZB) WsHandleData() {
z.Websocket.DataHandler <- err
continue
}
if result.No > 0 {
z.WebsocketConn.AddResponseWithID(result.No, fixedJSON)
continue
}
if result.Code > 0 && result.Code != 1000 {
z.Websocket.DataHandler <- fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, result.Message, wsErrCodes[result.Code])
continue
}
switch {
case strings.Contains(result.Channel, "markets"):
if !result.Success {
z.Websocket.DataHandler <- fmt.Errorf("zb_websocket.go error - unsuccessful market response %s", wsErrCodes[result.Code])
continue
}
var markets Markets
err := common.JSONDecode(result.Data, &markets)
if err != nil {
@@ -108,16 +88,14 @@ func (z *ZB) WsHandleData() {
case strings.Contains(result.Channel, "ticker"):
cPair := strings.Split(result.Channel, "_")
var ticker WsTicker
err := common.JSONDecode(fixedJSON, &ticker)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- exchange.TickerData{
z.Websocket.DataHandler <- wshandler.TickerData{
Timestamp: time.Unix(0, ticker.Date),
Pair: currency.NewPairFromString(cPair[0]),
AssetType: asset.Spot,
@@ -155,7 +133,6 @@ func (z *ZB) WsHandleData() {
channelInfo := strings.Split(result.Channel, "_")
cPair := currency.NewPairFromString(channelInfo[0])
var newOrderBook orderbook.Base
newOrderBook.Asks = asks
newOrderBook.Bids = bids
@@ -170,7 +147,7 @@ func (z *ZB) WsHandleData() {
continue
}
z.Websocket.DataHandler <- exchange.WebsocketOrderbookUpdate{
z.Websocket.DataHandler <- wshandler.WebsocketOrderbookUpdate{
Pair: cPair,
Asset: asset.Spot,
Exchange: z.GetName(),
@@ -183,7 +160,6 @@ func (z *ZB) WsHandleData() {
z.Websocket.DataHandler <- err
continue
}
// Most up to date trade
if len(trades.Data) == 0 {
continue
@@ -192,8 +168,7 @@ func (z *ZB) WsHandleData() {
channelInfo := strings.Split(result.Channel, "_")
cPair := currency.NewPairFromString(channelInfo[0])
z.Websocket.DataHandler <- exchange.TradeData{
z.Websocket.DataHandler <- wshandler.TradeData{
Timestamp: time.Unix(0, t.Date),
CurrencyPair: cPair,
AssetType: asset.Spot,
@@ -203,86 +178,6 @@ func (z *ZB) WsHandleData() {
Amount: t.Amount,
Side: t.TradeType,
}
case strings.EqualFold(result.Channel, "addSubUser"):
var response WsRequestResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
case strings.EqualFold(result.Channel, "getSubUserList"):
var response WsGetSubUserListResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
case strings.EqualFold(result.Channel, "doTransferFunds"):
var response WsRequestResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
case strings.EqualFold(result.Channel, "createSubUserKey"):
var response WsRequestResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
case strings.Contains(result.Channel, "_order"):
var response WsSubmitOrderResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
case strings.Contains(result.Channel, "_cancelorder"):
var response WsCancelOrderResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
case strings.Contains(result.Channel, "_getorders"):
var response WsGetOrdersResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
case strings.Contains(result.Channel, "_getorder"):
var response WsGetOrderResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
case strings.Contains(result.Channel, "_getordersignoretradetype"):
var response WsGetOrdersIgnoreTradeTypeResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
case strings.EqualFold(result.Channel, "getAccountInfo"):
var response WsGetAccountInfoResponse
err := common.JSONDecode(fixedJSON, &response)
if err != nil {
z.Websocket.DataHandler <- err
continue
}
z.Websocket.DataHandler <- response
default:
z.Websocket.DataHandler <- errors.New("zb_websocket.go error - unhandled websocket response")
continue
@@ -327,9 +222,9 @@ var wsErrCodes = map[int64]string{
// GenerateDefaultSubscriptions Adds default subscriptions to websocket to be handled by ManageSubscriptions()
func (z *ZB) GenerateDefaultSubscriptions() {
var subscriptions []exchange.WebsocketChannelSubscription
var subscriptions []wshandler.WebsocketChannelSubscription
// Tickerdata is its own channel
subscriptions = append(subscriptions, exchange.WebsocketChannelSubscription{
subscriptions = append(subscriptions, wshandler.WebsocketChannelSubscription{
Channel: "markets",
})
channels := []string{"%s_ticker", "%s_depth", "%s_trades"}
@@ -337,7 +232,7 @@ func (z *ZB) GenerateDefaultSubscriptions() {
for i := range channels {
for j := range enabledCurrencies {
enabledCurrencies[j].Delimiter = ""
subscriptions = append(subscriptions, exchange.WebsocketChannelSubscription{
subscriptions = append(subscriptions, wshandler.WebsocketChannelSubscription{
Channel: fmt.Sprintf(channels[i], enabledCurrencies[j].Lower().String()),
Currency: enabledCurrencies[j].Lower(),
})
@@ -347,108 +242,24 @@ func (z *ZB) GenerateDefaultSubscriptions() {
}
// Subscribe sends a websocket message to receive data from the channel
func (z *ZB) Subscribe(channelToSubscribe exchange.WebsocketChannelSubscription) error {
func (z *ZB) Subscribe(channelToSubscribe wshandler.WebsocketChannelSubscription) error {
subscriptionRequest := Subscription{
Event: zWebsocketAddChannel,
Channel: channelToSubscribe.Channel,
}
return z.wsSend(subscriptionRequest)
}
// WsSend sends data to the websocket server
func (z *ZB) wsSend(data interface{}) error {
z.wsRequestMtx.Lock()
defer z.wsRequestMtx.Unlock()
json, err := common.JSONEncode(data)
if err != nil {
return err
}
if z.Verbose {
log.Debugf(log.ExchangeSys, "%v sending message to websocket %v", z.Name, string(json))
}
return z.WebsocketConn.WriteMessage(websocket.TextMessage, json)
}
func (z *ZB) wsAddSubUser(username, password string) error {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsAddSubUserRequest{
Memo: "Memo",
Password: password,
SubUserName: username,
}
request.Channel = "addSubUser"
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
}
func (z *ZB) wsGetSubUserList() error {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsAuthenticatedRequest{}
request.Channel = "getSubUserList"
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
}
func (z *ZB) wsDoTransferFunds(pair currency.Code, amount float64, fromUserName, toUserName string) error {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsDoTransferFundsRequest{
Amount: amount,
Currency: pair,
FromUserName: fromUserName,
ToUserName: toUserName,
No: fmt.Sprintf("%v", time.Now().Unix()),
}
request.Channel = "doTransferFunds"
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
}
func (z *ZB) wsCreateSubUserKey(assetPerm, entrustPerm, leverPerm, moneyPerm bool, keyName, toUserID string) error {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsCreateSubUserKeyRequest{
AssetPerm: assetPerm,
EntrustPerm: entrustPerm,
KeyName: keyName,
LeverPerm: leverPerm,
MoneyPerm: moneyPerm,
No: fmt.Sprintf("%v", time.Now().Unix()),
ToUserID: toUserID,
}
request.Channel = "createSubUserKey"
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
return z.WebsocketConn.SendMessage(subscriptionRequest)
}
func (z *ZB) wsGenerateSignature(request interface{}) string {
jsonResponse, err := common.JSONEncode(request)
if err != nil {
log.Error(log.ExchangeSys, err)
return ""
}
hmac := crypto.GetHMAC(crypto.HashMD5,
jsonResponse,
[]byte(crypto.Sha1ToHex(z.API.Credentials.Secret)))
return fmt.Sprintf("%x", hmac)
}
func (z *ZB) wsFixInvalidJSON(json []byte) []byte {
@@ -465,97 +276,296 @@ func (z *ZB) wsFixInvalidJSON(json []byte) []byte {
return []byte(strings.Replace(string(json), string(matchingResults), fixedJSON, 1))
}
func (z *ZB) wsSubmitOrder(pair currency.Pair, amount, price float64, tradeType int64) error {
func (z *ZB) wsAddSubUser(username, password string) (*WsGetSubUserListResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsAddSubUserRequest{
Memo: "memo",
Password: password,
SubUserName: username,
}
request.Channel = "addSubUser"
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.No = z.WebsocketConn.GenerateMessageID(true)
request.Sign = z.wsGenerateSignature(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var genericResponse Generic
err = common.JSONDecode(resp, &genericResponse)
if err != nil {
return nil, err
}
if genericResponse.Code > 0 && genericResponse.Code != 1000 {
return nil, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, genericResponse.Message, wsErrCodes[genericResponse.Code])
}
var response WsGetSubUserListResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
return &response, nil
}
func (z *ZB) wsGetSubUserList() (*WsGetSubUserListResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsAuthenticatedRequest{}
request.Channel = "getSubUserList"
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.No = z.WebsocketConn.GenerateMessageID(true)
request.Sign = z.wsGenerateSignature(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var response WsGetSubUserListResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
if response.Code > 0 && response.Code != 1000 {
return &response, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, response.Message, wsErrCodes[response.Code])
}
return &response, nil
}
func (z *ZB) wsDoTransferFunds(pair currency.Code, amount float64, fromUserName, toUserName string) (*WsRequestResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsDoTransferFundsRequest{
Amount: amount,
Currency: pair,
FromUserName: fromUserName,
ToUserName: toUserName,
No: z.WebsocketConn.GenerateMessageID(true),
}
request.Channel = "doTransferFunds"
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var response WsRequestResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
if response.Code > 0 && response.Code != 1000 {
return &response, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, response.Message, wsErrCodes[response.Code])
}
return &response, nil
}
func (z *ZB) wsCreateSubUserKey(assetPerm, entrustPerm, leverPerm, moneyPerm bool, keyName, toUserID string) (*WsRequestResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsCreateSubUserKeyRequest{
AssetPerm: assetPerm,
EntrustPerm: entrustPerm,
KeyName: keyName,
LeverPerm: leverPerm,
MoneyPerm: moneyPerm,
No: z.WebsocketConn.GenerateMessageID(true),
ToUserID: toUserID,
}
request.Channel = "createSubUserKey"
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var response WsRequestResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
if response.Code > 0 && response.Code != 1000 {
return &response, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, response.Message, wsErrCodes[response.Code])
}
return &response, nil
}
func (z *ZB) wsSubmitOrder(pair currency.Pair, amount, price float64, tradeType int64) (*WsSubmitOrderResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsSubmitOrderRequest{
Amount: amount,
Price: price,
TradeType: tradeType,
No: fmt.Sprintf("%v", time.Now().Unix()),
No: z.WebsocketConn.GenerateMessageID(true),
}
request.Channel = fmt.Sprintf("%v_order", pair.String())
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var response WsSubmitOrderResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
if response.Code > 0 && response.Code != 1000 {
return &response, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, response.Message, wsErrCodes[response.Code])
}
return &response, nil
}
func (z *ZB) wsCancelOrder(pair currency.Pair, orderID int64) error {
func (z *ZB) wsCancelOrder(pair currency.Pair, orderID int64) (*WsCancelOrderResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsCancelOrderRequest{
ID: orderID,
No: z.WebsocketConn.GenerateMessageID(true),
}
request.Channel = fmt.Sprintf("%v_cancelorder", pair.String())
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var response WsCancelOrderResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
if response.Code > 0 && response.Code != 1000 {
return &response, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, response.Message, wsErrCodes[response.Code])
}
return &response, nil
}
func (z *ZB) wsGetOrder(pair currency.Pair, orderID int64) error {
func (z *ZB) wsGetOrder(pair currency.Pair, orderID int64) (*WsGetOrderResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsGetOrderRequest{
ID: orderID,
No: z.WebsocketConn.GenerateMessageID(true),
}
request.Channel = fmt.Sprintf("%v_getorder", pair.String())
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var response WsGetOrderResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
if response.Code > 0 && response.Code != 1000 {
return &response, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, response.Message, wsErrCodes[response.Code])
}
return &response, nil
}
func (z *ZB) wsGetOrders(pair currency.Pair, pageIndex, tradeType int64) error {
func (z *ZB) wsGetOrders(pair currency.Pair, pageIndex, tradeType int64) (*WsGetOrdersResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsGetOrdersRequest{
PageIndex: pageIndex,
TradeType: tradeType,
No: z.WebsocketConn.GenerateMessageID(true),
}
request.Channel = fmt.Sprintf("%v_getorders", pair.String())
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var response WsGetOrdersResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
if response.Code > 0 && response.Code != 1000 {
return &response, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, response.Message, wsErrCodes[response.Code])
}
return &response, nil
}
func (z *ZB) wsGetOrdersIgnoreTradeType(pair currency.Pair, pageIndex, pageSize int64) error {
func (z *ZB) wsGetOrdersIgnoreTradeType(pair currency.Pair, pageIndex, pageSize int64) (*WsGetOrdersIgnoreTradeTypeResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsGetOrdersIgnoreTradeTypeRequest{
PageIndex: pageIndex,
PageSize: pageSize,
No: z.WebsocketConn.GenerateMessageID(true),
}
request.Channel = fmt.Sprintf("%v_getordersignoretradetype", pair.String())
request.Event = zWebsocketAddChannel
request.Accesskey = z.API.Credentials.Key
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var response WsGetOrdersIgnoreTradeTypeResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
if response.Code > 0 && response.Code != 1000 {
return &response, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, response.Message, wsErrCodes[response.Code])
}
return &response, nil
}
func (z *ZB) wsGetAccountInfoRequest() error {
func (z *ZB) wsGetAccountInfoRequest() (*WsGetAccountInfoResponse, error) {
if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name)
}
request := WsAuthenticatedRequest{
Channel: "getaccountinfo",
Event: zWebsocketAddChannel,
Accesskey: z.API.Credentials.Key,
No: fmt.Sprintf("%v", time.Now().Unix()),
No: z.WebsocketConn.GenerateMessageID(true),
}
request.Sign = z.wsGenerateSignature(request)
return z.wsSend(request)
resp, err := z.WebsocketConn.SendMessageReturnResponse(request.No, request)
if err != nil {
return nil, err
}
var response WsGetAccountInfoResponse
err = common.JSONDecode(resp, &response)
if err != nil {
return nil, err
}
if response.Code > 0 && response.Code != 1000 {
return &response, fmt.Errorf("%v request failed, message: %v, error code: %v", z.Name, response.Message, wsErrCodes[response.Code])
}
return &response, nil
}

View File

@@ -3,22 +3,22 @@ package zb
import (
"encoding/json"
"github.com/thrasher-/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/currency"
)
// Subscription defines an initial subscription type to be sent
type Subscription struct {
Event string `json:"event"`
Channel string `json:"channel"`
No int64 `json:"no,string,omitempty"`
}
// Generic defines a generic fields associated with many return types
type Generic struct {
Code int64 `json:"code"`
Success bool `json:"success"`
Channel string `json:"channel"`
Message interface{} `json:"message"`
No string `json:"no"`
No int64 `json:"no,string,omitempty"`
Data json.RawMessage `json:"data"`
}
@@ -65,7 +65,7 @@ type WsAuthenticatedRequest struct {
Accesskey string `json:"accesskey"`
Channel string `json:"channel"`
Event string `json:"event"`
No string `json:"no,omitempty"`
No int64 `json:"no,string,omitempty"`
Sign string `json:"sign,omitempty"`
}
@@ -74,10 +74,11 @@ type WsAddSubUserRequest struct {
Accesskey string `json:"accesskey"`
Channel string `json:"channel"`
Event string `json:"event"`
Sign string `json:"sign,omitempty"`
Memo string `json:"memo"`
Password string `json:"password"`
SubUserName string `json:"subUserName"`
No int64 `json:"no,string,omtempty"`
Sign string `json:"sign,omitempty"`
}
// WsCreateSubUserKeyRequest data to add sub user keys
@@ -90,7 +91,7 @@ type WsCreateSubUserKeyRequest struct {
KeyName string `json:"keyName"`
LeverPerm bool `json:"leverPerm,string"`
MoneyPerm bool `json:"moneyPerm,string"`
No string `json:"no"`
No int64 `json:"no,string,omitempty"`
Sign string `json:"sign,omitempty"`
ToUserID string `json:"toUserId"`
}
@@ -103,7 +104,7 @@ type WsDoTransferFundsRequest struct {
Currency currency.Code `json:"currency"`
Event string `json:"event"`
FromUserName string `json:"fromUserName"`
No string `json:"no"`
No int64 `json:"no,string"`
Sign string `json:"sign,omitempty"`
ToUserName string `json:"toUserName"`
}
@@ -114,7 +115,7 @@ type WsGetSubUserListResponse struct {
Code int64 `json:"code"`
Channel string `json:"channel"`
Message []WsGetSubUserListResponseData `json:"message"`
No string `json:"no"`
No int64 `json:"no,string"`
}
// WsGetSubUserListResponseData user data
@@ -132,7 +133,7 @@ type WsRequestResponse struct {
Code int64 `json:"code"`
Channel string `json:"channel"`
Message interface{} `json:"message"`
No string `json:"no"`
No int64 `json:"no,string"`
}
// WsSubmitOrderRequest creates an order via ws
@@ -141,7 +142,7 @@ type WsSubmitOrderRequest struct {
Amount float64 `json:"amount,string"`
Channel string `json:"channel"`
Event string `json:"event"`
No string `json:"no,omitempty"`
No int64 `json:"no,string,omitempty"`
Price float64 `json:"price,string"`
Sign string `json:"sign,omitempty"`
TradeType int64 `json:"tradeType,string"`
@@ -150,7 +151,7 @@ type WsSubmitOrderRequest struct {
// WsSubmitOrderResponse data about submitted order
type WsSubmitOrderResponse struct {
Message string `json:"message"`
No string `json:"no"`
No int64 `json:"no,string"`
Data struct {
EntrustID int64 `json:"intrustID"`
} `json:"data"`
@@ -166,12 +167,13 @@ type WsCancelOrderRequest struct {
Event string `json:"event"`
ID int64 `json:"id"`
Sign string `json:"sign,omitempty"`
No int64 `json:"no,string"`
}
// WsCancelOrderResponse order cancel response
type WsCancelOrderResponse struct {
Message string `json:"message"`
No string `json:"no"`
No int64 `json:"no,string"`
Code int64 `json:"code"`
Channel string `json:"channel"`
Success bool `json:"success"`
@@ -184,12 +186,13 @@ type WsGetOrderRequest struct {
Event string `json:"event"`
ID int64 `json:"id"`
Sign string `json:"sign,omitempty"`
No int64 `json:"no,string"`
}
// WsGetOrderResponse contains order data
type WsGetOrderResponse struct {
Message string `json:"message"`
No string `json:"no"`
No int64 `json:"no,string"`
Code int64 `json:"code"`
Channel string `json:"channel"`
Success bool `json:"success"`
@@ -209,6 +212,7 @@ type WsGetOrderResponseData struct {
TradeDate int64 `json:"trade_date"`
TradeMoney float64 `json:"trade_money"`
Type int64 `json:"type"`
No int64 `json:"no,string"`
}
// WsGetOrdersRequest get more orders, with no orderID filtering
@@ -216,6 +220,7 @@ type WsGetOrdersRequest struct {
Accesskey string `json:"accesskey"`
Channel string `json:"channel"`
Event string `json:"event"`
No int64 `json:"no,string"`
PageIndex int64 `json:"pageIndex"`
TradeType int64 `json:"tradeType"`
Sign string `json:"sign,omitempty"`
@@ -224,7 +229,7 @@ type WsGetOrdersRequest struct {
// WsGetOrdersResponse contains orders data
type WsGetOrdersResponse struct {
Message string `json:"message"`
No string `json:"no"`
No int64 `json:"no,string"`
Code int64 `json:"code"`
Channel string `json:"channel"`
Success bool `json:"success"`
@@ -236,7 +241,7 @@ type WsGetOrdersIgnoreTradeTypeRequest struct {
Accesskey string `json:"accesskey"`
Channel string `json:"channel"`
Event string `json:"event"`
ID int64 `json:"id"`
No int64 `json:"no,string"`
PageIndex int64 `json:"pageIndex"`
PageSize int64 `json:"pageSize"`
Sign string `json:"sign,omitempty"`
@@ -245,7 +250,7 @@ type WsGetOrdersIgnoreTradeTypeRequest struct {
// WsGetOrdersIgnoreTradeTypeResponse contains orders data
type WsGetOrdersIgnoreTradeTypeResponse struct {
Message string `json:"message"`
No string `json:"no"`
No int64 `json:"no,string"`
Code int64 `json:"code"`
Channel string `json:"channel"`
Success bool `json:"success"`
@@ -255,12 +260,12 @@ type WsGetOrdersIgnoreTradeTypeResponse struct {
// WsGetAccountInfoResponse contains account data
type WsGetAccountInfoResponse struct {
Message string `json:"message"`
No string `json:"no"`
No int64 `json:"no,string"`
Data struct {
Coins []struct {
Freez float64 `json:"freez,string"`
EnName string `json:"enName"`
UnitDecimal int `json:"unitDecimal"`
UnitDecimal int64 `json:"unitDecimal"`
CnName string `json:"cnName"`
UnitTag string `json:"unitTag"`
Available float64 `json:"available,string"`
@@ -273,7 +278,7 @@ type WsGetAccountInfoResponse struct {
AuthMobileEnabled bool `json:"auth_mobile_enabled"`
} `json:"base"`
} `json:"data"`
Code int `json:"code"`
Code int64 `json:"code"`
Channel string `json:"channel"`
Success bool `json:"success"`
}

View File

@@ -8,15 +8,16 @@ import (
"sync"
"time"
"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/asset"
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-/gocryptotrader/exchanges/request"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
log "github.com/thrasher-/gocryptotrader/logger"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/currency"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
"github.com/thrasher-corp/gocryptotrader/exchanges/wshandler"
log "github.com/thrasher-corp/gocryptotrader/logger"
)
// GetDefaultConfig returns a default exchange config
@@ -91,11 +92,18 @@ func (z *ZB) SetDefaults() {
z.API.Endpoints.URLSecondaryDefault = zbMarketURL
z.API.Endpoints.URLSecondary = z.API.Endpoints.URLSecondaryDefault
z.API.Endpoints.WebsocketURL = zbWebsocketAPI
z.WebsocketInit()
z.Websocket.Functionality = exchange.WebsocketTickerSupported |
exchange.WebsocketOrderbookSupported |
exchange.WebsocketTradeDataSupported |
exchange.WebsocketSubscribeSupported
z.Websocket = wshandler.New()
z.Websocket.Functionality = wshandler.WebsocketTickerSupported |
wshandler.WebsocketOrderbookSupported |
wshandler.WebsocketTradeDataSupported |
wshandler.WebsocketSubscribeSupported |
wshandler.WebsocketAuthenticatedEndpointsSupported |
wshandler.WebsocketAccountDataSupported |
wshandler.WebsocketCancelOrderSupported |
wshandler.WebsocketSubmitOrderSupported |
wshandler.WebsocketMessageCorrelationSupported
z.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
z.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout
}
// Setup sets user configuration
@@ -110,14 +118,29 @@ func (z *ZB) Setup(exch *config.ExchangeConfig) error {
return err
}
return z.WebsocketSetup(z.WsConnect,
err = z.Websocket.Setup(z.WsConnect,
z.Subscribe,
nil,
exch.Name,
exch.Features.Enabled.Websocket,
exch.Verbose,
zbWebsocketAPI,
exch.API.Endpoints.WebsocketURL)
exch.API.Endpoints.WebsocketURL,
exch.API.AuthenticatedWebsocketSupport)
if err != nil {
return err
}
z.WebsocketConn = &wshandler.WebsocketConnection{
ExchangeName: z.Name,
URL: z.Websocket.GetWebsocketURL(),
ProxyURL: z.Websocket.GetProxyAddress(),
Verbose: z.Verbose,
RateLimit: zbWebsocketRateLimit,
ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout,
ResponseMaxLimit: exch.WebsocketResponseMaxLimit,
}
return nil
}
// Start starts the OKEX go routine
@@ -419,7 +442,7 @@ func (z *ZB) WithdrawFiatFundsToInternationalBank(withdrawRequest *exchange.Fiat
}
// GetWebsocket returns a pointer to the exchange websocket
func (z *ZB) GetWebsocket() (*exchange.Websocket, error) {
func (z *ZB) GetWebsocket() (*wshandler.Websocket, error) {
return z.Websocket, nil
}
@@ -532,19 +555,19 @@ func (z *ZB) GetOrderHistory(getOrdersRequest *exchange.GetOrdersRequest) ([]exc
// SubscribeToWebsocketChannels appends to ChannelsToSubscribe
// which lets websocket.manageSubscriptions handle subscribing
func (z *ZB) SubscribeToWebsocketChannels(channels []exchange.WebsocketChannelSubscription) error {
func (z *ZB) SubscribeToWebsocketChannels(channels []wshandler.WebsocketChannelSubscription) error {
z.Websocket.SubscribeToChannels(channels)
return nil
}
// UnsubscribeToWebsocketChannels removes from ChannelsToSubscribe
// which lets websocket.manageSubscriptions handle unsubscribing
func (z *ZB) UnsubscribeToWebsocketChannels(channels []exchange.WebsocketChannelSubscription) error {
func (z *ZB) UnsubscribeToWebsocketChannels(channels []wshandler.WebsocketChannelSubscription) error {
return common.ErrFunctionNotSupported
}
// GetSubscriptions returns a copied list of subscriptions
func (z *ZB) GetSubscriptions() ([]exchange.WebsocketChannelSubscription, error) {
func (z *ZB) GetSubscriptions() ([]wshandler.WebsocketChannelSubscription, error) {
return z.Websocket.GetSubscriptions(), nil
}