mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-05 23:16:53 +00:00
Feature: Add mock testing to ZB (#569)
* Adds mock testing to ZB
* STEALS improved time validation code from the original STOLEN validation code :D
* Mini fixes from review
* happy fun comment stealing
* Moves the loop checker earlier to ensure no double appendages
* Fixes sneaky test
* Fixes the important part where mock tests work instead of live tests
* Skips authenticated endpoints for mock testing.
* lint
* Updates candle wrapper functions to respect design
* basic linting fix
* Reverts configtest.json, updates readme to be way better, adds coverage to validateCandlesRequest
* Tiniest grammatical fix
* Fixes more outdated code references
* Closing out a high
* Fixes spacing
* Replaces all instances of 4 spaces in tmpl files with a tab
* fixes spacing and tab related readme issues once and for all 🤞
* tidy
* indentation violation identification situation
This commit is contained in:
@@ -31,8 +31,8 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader
|
||||
+ Individual package example below:
|
||||
|
||||
```go
|
||||
// Exchanges will be abstracted out in further updates and examples will be
|
||||
// supplied then
|
||||
// Exchanges will be abstracted out in further updates and examples will be
|
||||
// supplied then
|
||||
```
|
||||
|
||||
### How to do REST public/private calls
|
||||
@@ -48,9 +48,9 @@ main.go
|
||||
var z exchange.IBotExchange
|
||||
|
||||
for i := range bot.Exchanges {
|
||||
if bot.Exchanges[i].GetName() == "ZB" {
|
||||
z = bot.Exchanges[i]
|
||||
}
|
||||
if bot.Exchanges[i].GetName() == "ZB" {
|
||||
z = bot.Exchanges[i]
|
||||
}
|
||||
}
|
||||
|
||||
// Public calls - wrapper functions
|
||||
@@ -58,13 +58,13 @@ for i := range bot.Exchanges {
|
||||
// Fetches current ticker information
|
||||
tick, err := z.FetchTicker()
|
||||
if err != nil {
|
||||
// Handle error
|
||||
// Handle error
|
||||
}
|
||||
|
||||
// Fetches current orderbook information
|
||||
ob, err := z.FetchOrderbook()
|
||||
if err != nil {
|
||||
// Handle error
|
||||
// Handle error
|
||||
}
|
||||
|
||||
// Private calls - wrapper functions - make sure your APIKEY and APISECRET are
|
||||
@@ -73,7 +73,7 @@ if err != nil {
|
||||
// Fetches current account information
|
||||
accountInfo, err := z.GetAccountInfo()
|
||||
if err != nil {
|
||||
// Handle error
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
@@ -85,13 +85,13 @@ if err != nil {
|
||||
// Fetches current ticker information
|
||||
ticker, err := z.GetTicker()
|
||||
if err != nil {
|
||||
// Handle error
|
||||
// Handle error
|
||||
}
|
||||
|
||||
// Fetches current orderbook information
|
||||
ob, err := z.GetOrderBook()
|
||||
if err != nil {
|
||||
// Handle error
|
||||
// Handle error
|
||||
}
|
||||
|
||||
// Private calls - make sure your APIKEY and APISECRET are set and
|
||||
@@ -100,21 +100,21 @@ if err != nil {
|
||||
// GetUserInfo returns account info
|
||||
accountInfo, err := z.GetUserInfo(...)
|
||||
if err != nil {
|
||||
// Handle error
|
||||
// Handle error
|
||||
}
|
||||
|
||||
// Submits an order and the exchange and returns its tradeID
|
||||
tradeID, err := z.Trade(...)
|
||||
if err != nil {
|
||||
// Handle error
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
### How to do LongPolling public/private calls
|
||||
|
||||
```go
|
||||
// Exchanges will be abstracted out in further updates and examples will be
|
||||
// supplied then
|
||||
// Exchanges will be abstracted out in further updates and examples will be
|
||||
// supplied then
|
||||
```
|
||||
|
||||
### Please click GoDocs chevron above to view current GoDoc information for this package
|
||||
|
||||
@@ -19,10 +19,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
zbTradeURL = "http://api.zb.live/data"
|
||||
zbMarketURL = "https://trade.zb.live/api"
|
||||
zbAPIVersion = "v1"
|
||||
|
||||
zbTradeURL = "http://api.zb.live"
|
||||
zbMarketURL = "https://trade.zb.live/api"
|
||||
zbAPIVersion = "v1"
|
||||
zbData = "data"
|
||||
zbAccountInfo = "getAccountInfo"
|
||||
zbMarkets = "markets"
|
||||
zbKline = "kline"
|
||||
@@ -136,7 +136,7 @@ func (z *ZB) GetOrders(currency string, pageindex, side int64) ([]Order, error)
|
||||
// GetMarkets returns market information including pricing, symbols and
|
||||
// each symbols decimal precision
|
||||
func (z *ZB) GetMarkets() (map[string]MarketResponseItem, error) {
|
||||
endpoint := fmt.Sprintf("%s/%s/%s", z.API.Endpoints.URL, zbAPIVersion, zbMarkets)
|
||||
endpoint := fmt.Sprintf("%s/%s/%s/%s", z.API.Endpoints.URL, zbData, zbAPIVersion, zbMarkets)
|
||||
|
||||
var res map[string]MarketResponseItem
|
||||
err := z.SendHTTPRequest(endpoint, &res, request.UnAuth)
|
||||
@@ -163,7 +163,7 @@ func (z *ZB) GetLatestSpotPrice(symbol string) (float64, error) {
|
||||
|
||||
// GetTicker returns a ticker for a given symbol
|
||||
func (z *ZB) GetTicker(symbol string) (TickerResponse, error) {
|
||||
urlPath := fmt.Sprintf("%s/%s/%s?market=%s", z.API.Endpoints.URL, zbAPIVersion, zbTicker, symbol)
|
||||
urlPath := fmt.Sprintf("%s/%s/%s/%s?market=%s", z.API.Endpoints.URL, zbData, zbAPIVersion, zbTicker, symbol)
|
||||
var res TickerResponse
|
||||
err := z.SendHTTPRequest(urlPath, &res, request.UnAuth)
|
||||
return res, err
|
||||
@@ -171,7 +171,7 @@ func (z *ZB) GetTicker(symbol string) (TickerResponse, error) {
|
||||
|
||||
// GetTickers returns ticker data for all supported symbols
|
||||
func (z *ZB) GetTickers() (map[string]TickerChildResponse, error) {
|
||||
urlPath := fmt.Sprintf("%s/%s/%s", z.API.Endpoints.URL, zbAPIVersion, zbTickers)
|
||||
urlPath := fmt.Sprintf("%s/%s/%s/%s", z.API.Endpoints.URL, zbData, zbAPIVersion, zbTickers)
|
||||
resp := make(map[string]TickerChildResponse)
|
||||
err := z.SendHTTPRequest(urlPath, &resp, request.UnAuth)
|
||||
return resp, err
|
||||
@@ -179,7 +179,7 @@ func (z *ZB) GetTickers() (map[string]TickerChildResponse, error) {
|
||||
|
||||
// GetOrderbook returns the orderbook for a given symbol
|
||||
func (z *ZB) GetOrderbook(symbol string) (OrderbookResponse, error) {
|
||||
urlPath := fmt.Sprintf("%s/%s/%s?market=%s", z.API.Endpoints.URL, zbAPIVersion, zbDepth, symbol)
|
||||
urlPath := fmt.Sprintf("%s/%s/%s/%s?market=%s", z.API.Endpoints.URL, zbData, zbAPIVersion, zbDepth, symbol)
|
||||
var res OrderbookResponse
|
||||
|
||||
err := z.SendHTTPRequest(urlPath, &res, request.UnAuth)
|
||||
@@ -217,7 +217,7 @@ func (z *ZB) GetSpotKline(arg KlinesRequestParams) (KLineResponse, error) {
|
||||
vals.Set("size", fmt.Sprintf("%d", arg.Size))
|
||||
}
|
||||
|
||||
urlPath := fmt.Sprintf("%s/%s/%s?%s", z.API.Endpoints.URL, zbAPIVersion, zbKline, vals.Encode())
|
||||
urlPath := fmt.Sprintf("%s/%s/%s/%s?%s", z.API.Endpoints.URL, zbData, zbAPIVersion, zbKline, vals.Encode())
|
||||
|
||||
var res KLineResponse
|
||||
var rawKlines map[string]interface{}
|
||||
|
||||
41
exchanges/zb/zb_live_test.go
Normal file
41
exchanges/zb/zb_live_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
//+build mock_test_off
|
||||
|
||||
// This will build if build tag mock_test_off is parsed and will do live testing
|
||||
// using all tests in (exchange)_test.go
|
||||
package zb
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||
)
|
||||
|
||||
var mockTests = false
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cfg := config.GetConfig()
|
||||
err := cfg.LoadConfig("../../testdata/configtest.json", true)
|
||||
if err != nil {
|
||||
log.Fatal("ZB load config error", err)
|
||||
}
|
||||
zbConfig, err := cfg.GetExchangeConfig("ZB")
|
||||
if err != nil {
|
||||
log.Fatal("ZB Setup() init error", err)
|
||||
}
|
||||
zbConfig.API.AuthenticatedSupport = true
|
||||
zbConfig.API.Credentials.Key = apiKey
|
||||
zbConfig.API.Credentials.Secret = apiSecret
|
||||
z.SetDefaults()
|
||||
z.Websocket = sharedtestvalues.NewTestWebsocket()
|
||||
err = z.Setup(zbConfig)
|
||||
if err != nil {
|
||||
log.Fatal("ZB setup error", err)
|
||||
}
|
||||
log.Printf(sharedtestvalues.LiveTesting, z.Name, z.API.Endpoints.URL)
|
||||
z.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride()
|
||||
z.Websocket.TrafficAlert = sharedtestvalues.GetWebsocketStructChannelOverride()
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
55
exchanges/zb/zb_mock_test.go
Normal file
55
exchanges/zb/zb_mock_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
//+build !mock_test_off
|
||||
|
||||
// This will build if build tag mock_test_off is not parsed and will try to mock
|
||||
// all tests in _test.go
|
||||
package zb
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/mock"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||
)
|
||||
|
||||
const mockfile = "../../testdata/http_mock/zb/zb.json"
|
||||
|
||||
var mockTests = true
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cfg := config.GetConfig()
|
||||
err := cfg.LoadConfig("../../testdata/configtest.json", true)
|
||||
if err != nil {
|
||||
log.Fatal("ZB load config error", err)
|
||||
}
|
||||
var zbConfig *config.ExchangeConfig
|
||||
zbConfig, err = cfg.GetExchangeConfig("ZB")
|
||||
if err != nil {
|
||||
log.Fatal("ZB Setup() init error", err)
|
||||
}
|
||||
zbConfig.API.AuthenticatedSupport = true
|
||||
zbConfig.API.AuthenticatedWebsocketSupport = true
|
||||
zbConfig.API.Credentials.Key = apiKey
|
||||
zbConfig.API.Credentials.Secret = apiSecret
|
||||
z.SkipAuthCheck = true
|
||||
z.SetDefaults()
|
||||
z.Websocket = sharedtestvalues.NewTestWebsocket()
|
||||
err = z.Setup(zbConfig)
|
||||
if err != nil {
|
||||
log.Fatal("ZB setup error", err)
|
||||
}
|
||||
|
||||
serverDetails, newClient, err := mock.NewVCRServer(mockfile)
|
||||
if err != nil {
|
||||
log.Fatalf("Mock server error %s", err)
|
||||
}
|
||||
z.HTTPClient = newClient
|
||||
z.API.Endpoints.URL = serverDetails
|
||||
log.Printf(sharedtestvalues.MockTesting,
|
||||
z.Name,
|
||||
z.API.Endpoints.URL)
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
@@ -3,23 +3,20 @@ package zb
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
||||
"github.com/thrasher-corp/gocryptotrader/core"
|
||||
"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/kline"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
|
||||
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
|
||||
)
|
||||
@@ -29,39 +26,20 @@ const (
|
||||
apiKey = ""
|
||||
apiSecret = ""
|
||||
canManipulateRealOrders = false
|
||||
testCurrency = "btc_usdt"
|
||||
)
|
||||
|
||||
var z ZB
|
||||
var wsSetupRan bool
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
z.SetDefaults()
|
||||
cfg := config.GetConfig()
|
||||
err := cfg.LoadConfig("../../testdata/configtest.json", true)
|
||||
if err != nil {
|
||||
log.Fatal("ZB load config error", err)
|
||||
}
|
||||
zbConfig, err := cfg.GetExchangeConfig("ZB")
|
||||
if err != nil {
|
||||
log.Fatal("ZB Setup() init error", err)
|
||||
}
|
||||
zbConfig.API.AuthenticatedSupport = true
|
||||
zbConfig.API.AuthenticatedWebsocketSupport = true
|
||||
zbConfig.API.Credentials.Key = apiKey
|
||||
zbConfig.API.Credentials.Secret = apiSecret
|
||||
z.Websocket = sharedtestvalues.NewTestWebsocket()
|
||||
err = z.Setup(zbConfig)
|
||||
if err != nil {
|
||||
log.Fatal("ZB setup error", err)
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func setupWsAuth(t *testing.T) {
|
||||
if wsSetupRan {
|
||||
return
|
||||
}
|
||||
if !z.Websocket.IsEnabled() && !z.API.AuthenticatedWebsocketSupport || !z.ValidateAPICredentials() || !canManipulateRealOrders {
|
||||
if !z.Websocket.IsEnabled() &&
|
||||
!z.API.AuthenticatedWebsocketSupport ||
|
||||
!z.ValidateAPICredentials() ||
|
||||
!canManipulateRealOrders {
|
||||
t.Skip(stream.WebsocketNotEnabled)
|
||||
}
|
||||
var dialer websocket.Dialer
|
||||
@@ -81,7 +59,7 @@ func TestSpotNewOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
arg := SpotNewOrderRequestParams{
|
||||
Symbol: "btc_usdt",
|
||||
Symbol: testCurrency,
|
||||
Type: SpotNewOrderRequestParamsTypeSell,
|
||||
Amount: 0.01,
|
||||
Price: 10246.1,
|
||||
@@ -99,7 +77,7 @@ func TestCancelExistingOrder(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
err := z.CancelExistingOrder(20180629145864850, "btc_usdt")
|
||||
err := z.CancelExistingOrder(20180629145864850, testCurrency)
|
||||
if err != nil {
|
||||
t.Errorf("ZB CancelExistingOrder: %s", err)
|
||||
}
|
||||
@@ -107,7 +85,7 @@ func TestCancelExistingOrder(t *testing.T) {
|
||||
|
||||
func TestGetLatestSpotPrice(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := z.GetLatestSpotPrice("btc_usdt")
|
||||
_, err := z.GetLatestSpotPrice(testCurrency)
|
||||
if err != nil {
|
||||
t.Errorf("ZB GetLatestSpotPrice: %s", err)
|
||||
}
|
||||
@@ -115,7 +93,7 @@ func TestGetLatestSpotPrice(t *testing.T) {
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := z.GetTicker("btc_usdt")
|
||||
_, err := z.GetTicker(testCurrency)
|
||||
if err != nil {
|
||||
t.Errorf("ZB GetTicker: %s", err)
|
||||
}
|
||||
@@ -131,7 +109,7 @@ func TestGetTickers(t *testing.T) {
|
||||
|
||||
func TestGetOrderbook(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := z.GetOrderbook("btc_usdt")
|
||||
_, err := z.GetOrderbook(testCurrency)
|
||||
if err != nil {
|
||||
t.Errorf("ZB GetTicker: %s", err)
|
||||
}
|
||||
@@ -145,18 +123,6 @@ func TestGetMarkets(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSpotKline(t *testing.T) {
|
||||
arg := KlinesRequestParams{
|
||||
Symbol: "btc_usdt",
|
||||
Type: kline.OneMin.Short() + "in",
|
||||
Size: 10,
|
||||
}
|
||||
_, err := z.GetSpotKline(arg)
|
||||
if err != nil {
|
||||
t.Errorf("ZB GetSpotKline: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func setFeeBuilder() *exchange.FeeBuilder {
|
||||
return &exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
@@ -172,6 +138,7 @@ func setFeeBuilder() *exchange.FeeBuilder {
|
||||
|
||||
// TestGetFeeByTypeOfflineTradeFee logic test
|
||||
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
t.Parallel()
|
||||
var feeBuilder = setFeeBuilder()
|
||||
z.GetFeeByType(feeBuilder)
|
||||
if !z.ValidateAPICredentials() {
|
||||
@@ -270,6 +237,9 @@ func TestFormatWithdrawPermissions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetActiveOrders(t *testing.T) {
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
var getOrdersRequest = order.GetOrdersRequest{
|
||||
Type: order.AnyType,
|
||||
Pairs: []currency.Pair{currency.NewPair(currency.XRP,
|
||||
@@ -278,13 +248,16 @@ func TestGetActiveOrders(t *testing.T) {
|
||||
|
||||
_, err := z.GetActiveOrders(&getOrdersRequest)
|
||||
if z.ValidateAPICredentials() && err != nil {
|
||||
t.Errorf("Could not get open orders: %s", err)
|
||||
t.Error(err)
|
||||
} else if !z.ValidateAPICredentials() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
t.Error("expecting an error when no keys are set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderHistory(t *testing.T) {
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
var getOrdersRequest = order.GetOrdersRequest{
|
||||
Type: order.AnyType,
|
||||
Side: order.Buy,
|
||||
@@ -294,9 +267,9 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
|
||||
_, err := z.GetOrderHistory(&getOrdersRequest)
|
||||
if z.ValidateAPICredentials() && err != nil {
|
||||
t.Errorf("Could not get order history: %s", err)
|
||||
t.Error(err)
|
||||
} else if !z.ValidateAPICredentials() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
t.Error("expecting an error when no keys are set")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,10 +278,12 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
|
||||
func TestSubmitOrder(t *testing.T) {
|
||||
if z.ValidateAPICredentials() && !canManipulateRealOrders {
|
||||
t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v",
|
||||
z.API.Credentials.Key,
|
||||
t.Skip(fmt.Sprintf("Can place orders: %v",
|
||||
canManipulateRealOrders))
|
||||
}
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
|
||||
var orderSubmission = &order.Submit{
|
||||
Pair: currency.Pair{
|
||||
@@ -324,10 +299,13 @@ func TestSubmitOrder(t *testing.T) {
|
||||
AssetType: asset.Spot,
|
||||
}
|
||||
response, err := z.SubmitOrder(orderSubmission)
|
||||
if z.ValidateAPICredentials() && (err != nil || !response.IsOrderPlaced) {
|
||||
t.Errorf("Order failed to be placed: %v", err)
|
||||
if z.ValidateAPICredentials() && err != nil {
|
||||
t.Error(err)
|
||||
} else if !z.ValidateAPICredentials() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
t.Error("expecting an error when no keys are set")
|
||||
}
|
||||
if z.ValidateAPICredentials() && response.OrderID == "" {
|
||||
t.Error("expected order id")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,6 +313,9 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
if z.ValidateAPICredentials() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
|
||||
currencyPair := currency.NewPair(currency.XRP, currency.USDT)
|
||||
var orderCancellation = &order.Cancel{
|
||||
@@ -346,11 +327,10 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
err := z.CancelOrder(orderCancellation)
|
||||
if !z.ValidateAPICredentials() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if z.ValidateAPICredentials() && err != nil {
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
t.Error(err)
|
||||
} else if !z.ValidateAPICredentials() && err == nil {
|
||||
t.Error("expecting an error when no keys are set")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,6 +338,9 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
if z.ValidateAPICredentials() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
|
||||
currencyPair := currency.NewPair(currency.XRP, currency.USDT)
|
||||
var orderCancellation = &order.Cancel{
|
||||
@@ -370,19 +353,20 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
|
||||
resp, err := z.CancelAllOrders(orderCancellation)
|
||||
|
||||
if !z.ValidateAPICredentials() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if z.ValidateAPICredentials() && err != nil {
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
t.Error(err)
|
||||
} else if !z.ValidateAPICredentials() && err == nil {
|
||||
t.Error("expecting an error when no keys are set")
|
||||
}
|
||||
|
||||
if len(resp.Status) > 0 {
|
||||
t.Errorf("%v orders failed to cancel", len(resp.Status))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccountInfo(t *testing.T) {
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
if z.ValidateAPICredentials() {
|
||||
_, err := z.UpdateAccountInfo()
|
||||
if err != nil {
|
||||
@@ -397,6 +381,9 @@ func TestGetAccountInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestModifyOrder(t *testing.T) {
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
if z.ValidateAPICredentials() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
@@ -407,6 +394,13 @@ func TestModifyOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWithdraw(t *testing.T) {
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
if z.ValidateAPICredentials() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
withdrawCryptoRequest := withdraw.Request{
|
||||
Crypto: withdraw.CryptoRequest{
|
||||
Address: core.BitcoinDonationAddress,
|
||||
@@ -417,20 +411,18 @@ func TestWithdraw(t *testing.T) {
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
|
||||
if z.ValidateAPICredentials() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
_, err := z.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest)
|
||||
if !z.ValidateAPICredentials() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if z.ValidateAPICredentials() && err != nil {
|
||||
t.Errorf("Withdraw failed to be placed: %v", err)
|
||||
t.Error(err)
|
||||
} else if !z.ValidateAPICredentials() && err == nil {
|
||||
t.Error("expecting an error when no keys are set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawFiat(t *testing.T) {
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
if z.ValidateAPICredentials() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
@@ -443,6 +435,9 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWithdrawInternationalBank(t *testing.T) {
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
if z.ValidateAPICredentials() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
@@ -455,6 +450,9 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if mockTests {
|
||||
t.Skip("skipping authenticated function for mock testing")
|
||||
}
|
||||
if z.ValidateAPICredentials() {
|
||||
_, err := z.GetDepositAddress(currency.BTC, "")
|
||||
if err != nil {
|
||||
@@ -833,30 +831,59 @@ func TestWsCreateSubUserResponse(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSpotKline(t *testing.T) {
|
||||
arg := KlinesRequestParams{
|
||||
Symbol: testCurrency,
|
||||
Type: kline.OneMin.Short() + "in",
|
||||
Size: int64(z.Features.Enabled.Kline.ResultLimit),
|
||||
}
|
||||
if mockTests {
|
||||
startTime := time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC)
|
||||
arg.Since = convert.UnixMillis(startTime)
|
||||
arg.Type = "1day"
|
||||
}
|
||||
|
||||
_, err := z.GetSpotKline(arg)
|
||||
if err != nil {
|
||||
t.Errorf("ZB GetSpotKline: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetHistoricCandles(t *testing.T) {
|
||||
currencyPair, err := currency.NewPairFromString("btc_usdt")
|
||||
currencyPair, err := currency.NewPairFromString(testCurrency)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
startTime := time.Now().Add(-time.Hour * 1)
|
||||
_, err = z.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.OneHour)
|
||||
endTime := time.Now()
|
||||
if mockTests {
|
||||
startTime = time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC)
|
||||
endTime = time.Date(2020, 9, 2, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
_, err = z.GetHistoricCandles(currencyPair, asset.Spot, startTime, endTime, kline.OneDay)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = z.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.Interval(time.Hour*7))
|
||||
_, err = z.GetHistoricCandles(currencyPair, asset.Spot, startTime, endTime, kline.Interval(time.Hour*7))
|
||||
if err == nil {
|
||||
t.Fatal("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetHistoricCandlesExtended(t *testing.T) {
|
||||
currencyPair, err := currency.NewPairFromString("btc_usdt")
|
||||
currencyPair, err := currency.NewPairFromString(testCurrency)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
start := time.Now().AddDate(0, -2, 0)
|
||||
end := time.Now()
|
||||
_, err = z.GetHistoricCandlesExtended(currencyPair, asset.Spot, start, end, kline.OneHour)
|
||||
startTime := time.Now().Add(-time.Hour * 1)
|
||||
endTime := time.Now()
|
||||
if mockTests {
|
||||
startTime = time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC)
|
||||
endTime = time.Date(2020, 9, 2, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
_, err = z.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, endTime, kline.OneDay)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -912,3 +939,40 @@ func Test_FormatExchangeKlineInterval(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateCandlesRequest(t *testing.T) {
|
||||
_, err := z.validateCandlesRequest(currency.Pair{}, "", time.Time{}, time.Time{}, kline.Interval(-1))
|
||||
if err != nil && err.Error() != "invalid time range supplied. Start: 0001-01-01 00:00:00 +0000 UTC End 0001-01-01 00:00:00 +0000 UTC" {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = z.validateCandlesRequest(currency.Pair{}, "", time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC), time.Time{}, kline.Interval(-1))
|
||||
if err != nil && err.Error() != "invalid time range supplied. Start: 2020-01-01 01:01:01.000000001 +0000 UTC End 0001-01-01 00:00:00 +0000 UTC" {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = z.validateCandlesRequest(currency.Pair{}, asset.Spot, time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC), time.Date(2020, 1, 1, 1, 1, 1, 3, time.UTC), kline.OneHour)
|
||||
if err != nil && err.Error() != "pair not enabled" {
|
||||
t.Error(err)
|
||||
}
|
||||
var p currency.Pair
|
||||
p, err = currency.NewPairFromString(testCurrency)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var item kline.Item
|
||||
item, err = z.validateCandlesRequest(p, asset.Spot, time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC), time.Date(2020, 1, 1, 1, 1, 1, 3, time.UTC), kline.OneHour)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !item.Pair.Equal(p) {
|
||||
t.Errorf("unexpected result, expected %v, received %v", p, item.Pair)
|
||||
}
|
||||
if item.Asset != asset.Spot {
|
||||
t.Errorf("unexpected result, expected %v, received %v", asset.Spot, item.Asset)
|
||||
}
|
||||
if item.Interval != kline.OneHour {
|
||||
t.Errorf("unexpected result, expected %v, received %v", kline.OneHour, item.Interval)
|
||||
}
|
||||
if item.Exchange != z.Name {
|
||||
t.Errorf("unexpected result, expected %v, received %v", z.Name, item.Exchange)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ type KlinesRequestParams struct {
|
||||
Symbol string // 交易对, zb_qc,zb_usdt,zb_btc...
|
||||
Type string // K线类型, 1min, 3min, 15min, 30min, 1hour......
|
||||
Since int64 // 从这个时间戳之后的
|
||||
Size int // 返回数据的条数限制(默认为1000,如果返回数据多于1000条,那么只返回1000条)
|
||||
Size int64 // 返回数据的条数限制(默认为1000,如果返回数据多于1000条,那么只返回1000条)
|
||||
}
|
||||
|
||||
// KLineResponseData Kline Data
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
@@ -590,7 +591,7 @@ func (z *ZB) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdraw.Requ
|
||||
|
||||
// GetFeeByType returns an estimate of fee based on type of transaction
|
||||
func (z *ZB) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) {
|
||||
if !z.AllowAuthenticatedRequest() && // Todo check connection status
|
||||
if (!z.AllowAuthenticatedRequest() || z.SkipAuthCheck) && // Todo check connection status
|
||||
feeBuilder.FeeType == exchange.CryptocurrencyTradeFee {
|
||||
feeBuilder.FeeType = exchange.OfflineTradeFee
|
||||
}
|
||||
@@ -770,33 +771,29 @@ func (z *ZB) FormatExchangeKlineInterval(in kline.Interval) string {
|
||||
}
|
||||
|
||||
// GetHistoricCandles returns candles between a time period for a set time interval
|
||||
func (z *ZB) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) {
|
||||
if err := z.ValidateKline(pair, a, interval); err != nil {
|
||||
func (z *ZB) GetHistoricCandles(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) {
|
||||
ret, err := z.validateCandlesRequest(p, a, start, end, interval)
|
||||
if err != nil {
|
||||
return kline.Item{}, err
|
||||
}
|
||||
|
||||
formattedPair, err := z.FormatExchangeCurrency(pair, a)
|
||||
p, err = z.FormatExchangeCurrency(p, a)
|
||||
if err != nil {
|
||||
return kline.Item{}, err
|
||||
}
|
||||
|
||||
klineParams := KlinesRequestParams{
|
||||
Type: z.FormatExchangeKlineInterval(interval),
|
||||
Symbol: formattedPair.String(),
|
||||
Symbol: p.String(),
|
||||
Since: convert.UnixMillis(start),
|
||||
Size: int64(z.Features.Enabled.Kline.ResultLimit),
|
||||
}
|
||||
|
||||
candles, err := z.GetSpotKline(klineParams)
|
||||
var candles KLineResponse
|
||||
candles, err = z.GetSpotKline(klineParams)
|
||||
if err != nil {
|
||||
return kline.Item{}, err
|
||||
}
|
||||
|
||||
ret := kline.Item{
|
||||
Exchange: z.Name,
|
||||
Pair: pair,
|
||||
Asset: a,
|
||||
Interval: interval,
|
||||
}
|
||||
|
||||
for x := range candles.Data {
|
||||
if candles.Data[x].KlineTime.Before(start) || candles.Data[x].KlineTime.After(end) {
|
||||
continue
|
||||
@@ -804,7 +801,7 @@ func (z *ZB) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end tim
|
||||
ret.Candles = append(ret.Candles, kline.Candle{
|
||||
Time: candles.Data[x].KlineTime,
|
||||
Open: candles.Data[x].Open,
|
||||
High: candles.Data[x].Close,
|
||||
High: candles.Data[x].High,
|
||||
Low: candles.Data[x].Low,
|
||||
Close: candles.Data[x].Close,
|
||||
Volume: candles.Data[x].Volume,
|
||||
@@ -817,5 +814,77 @@ func (z *ZB) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end tim
|
||||
|
||||
// GetHistoricCandlesExtended returns candles between a time period for a set time interval
|
||||
func (z *ZB) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) {
|
||||
return z.GetHistoricCandles(p, a, start, end, interval)
|
||||
ret, err := z.validateCandlesRequest(p, a, start, end, interval)
|
||||
if err != nil {
|
||||
return kline.Item{}, err
|
||||
}
|
||||
|
||||
p, err = z.FormatExchangeCurrency(p, a)
|
||||
if err != nil {
|
||||
return kline.Item{}, err
|
||||
}
|
||||
|
||||
startTime := start
|
||||
allKlines:
|
||||
for {
|
||||
klineParams := KlinesRequestParams{
|
||||
Type: z.FormatExchangeKlineInterval(interval),
|
||||
Symbol: p.String(),
|
||||
Since: convert.UnixMillis(startTime),
|
||||
Size: int64(z.Features.Enabled.Kline.ResultLimit),
|
||||
}
|
||||
|
||||
candles, err := z.GetSpotKline(klineParams)
|
||||
if err != nil {
|
||||
return kline.Item{}, err
|
||||
}
|
||||
|
||||
for x := range candles.Data {
|
||||
if candles.Data[x].KlineTime.Before(start) || candles.Data[x].KlineTime.After(end) {
|
||||
continue
|
||||
}
|
||||
if startTime.Equal(candles.Data[x].KlineTime) {
|
||||
// no new data has been sent
|
||||
break allKlines
|
||||
}
|
||||
ret.Candles = append(ret.Candles, kline.Candle{
|
||||
Time: candles.Data[x].KlineTime,
|
||||
Open: candles.Data[x].Open,
|
||||
High: candles.Data[x].High,
|
||||
Low: candles.Data[x].Low,
|
||||
Close: candles.Data[x].Close,
|
||||
Volume: candles.Data[x].Volume,
|
||||
})
|
||||
if x == len(candles.Data)-1 {
|
||||
startTime = candles.Data[x].KlineTime
|
||||
}
|
||||
}
|
||||
if len(candles.Data) != int(z.Features.Enabled.Kline.ResultLimit) {
|
||||
break allKlines
|
||||
}
|
||||
}
|
||||
|
||||
ret.SortCandlesByTimestamp(false)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (z *ZB) validateCandlesRequest(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) {
|
||||
if start.Equal(end) ||
|
||||
end.After(time.Now()) ||
|
||||
end.Before(start) ||
|
||||
(start.IsZero() && !end.IsZero()) {
|
||||
return kline.Item{}, fmt.Errorf("invalid time range supplied. Start: %v End %v",
|
||||
start,
|
||||
end)
|
||||
}
|
||||
if err := z.ValidateKline(p, a, interval); err != nil {
|
||||
return kline.Item{}, err
|
||||
}
|
||||
|
||||
return kline.Item{
|
||||
Exchange: z.Name,
|
||||
Pair: p,
|
||||
Asset: a,
|
||||
Interval: interval,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user