Engine: Protocol Features, coverage, types, BTC markets websocket (#368)

* Attempts to update orderbook so it doesn't need to sort

* Reverts the ws ob stuff. Gets rid of sorting because it happens later. Adds some exchange features

* update existing feature lists. Expands list definition to match my emotions

* Adds bithumb bitmex and bitstamp. adds a couple more types

* Features for you, features for me, features for bittrex, btcmarkets, btse, coinbasepro, coinut, exmo, gateio and gemini

* Features for hitbtc, huobi, itbit, kraken, lakebtc, lbank, localbitcoins, okcoin, okex, poloniex, yobit, zb

* Who can forget good old alphapoint?

* Adds btcmarksets websocket :glitch_crab: fixes alphapoint features

* Adds extra data not in the documentation :/

* Replaces websocket features by using protocol features. However, it breaks it due to import cycles. I'm not sure what I'll do just yet

* Removes import cycle via duplicate structs.

* Increases coverage of config with `TestCheckCurrencyConfigValues`. Moves all currency pair package types into their own files or places it at the bottom of files if necessary

* Increase coverage in code.go

* One way of determining a test has failed, is when to it fails. Removed redundant explanation

* Increases code coverage of conversion

* Lint fixes

* Fixes orderbook tests

* Re-adds sorting because its important to still have the internal pre-processed orderbook to be representative of a real orderbook

* Secret lints that did not show up via Windows linting

* Adds protocol package to contain exchange features

* Fixes protocol implementation

* Fixes ws tests

* Addresses the following: Removes st-st-stutters in config types, changes GetAvailableForexProviders -> GetSupportedForexProviders, removes errors from tests where error is nil, removes orderbook setup when not necessary, removes import newlines, removes false bools from declaration, changes should of to should have

* imports and casing

* Fixes two more nil error checks
This commit is contained in:
Scott
2019-10-22 10:56:20 +11:00
committed by Adrian Gallagher
parent ec0ed1c1e5
commit ccfcdf26aa
156 changed files with 5228 additions and 4337 deletions

View File

@@ -32,11 +32,11 @@ func TestSetup(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig("../../testdata/configtest.json", true)
if err != nil {
t.Fatal("Test Failed - Bitmex load config error", err)
t.Fatal("Bitmex load config error", err)
}
bitmexConfig, err := cfg.GetExchangeConfig("Bitmex")
if err != nil {
t.Error("Test Failed - Bitmex Setup() init error")
t.Error("Bitmex Setup() init error")
}
bitmexConfig.API.AuthenticatedSupport = true
@@ -46,7 +46,7 @@ func TestSetup(t *testing.T) {
err = b.Setup(bitmexConfig)
if err != nil {
t.Fatal("Test Failed - Bitmex setup error", err)
t.Fatal("Bitmex setup error", err)
}
}
@@ -59,42 +59,42 @@ func TestStart(t *testing.T) {
func TestGetUrgentAnnouncement(t *testing.T) {
_, err := b.GetUrgentAnnouncement()
if err == nil {
t.Error("test failed - GetUrgentAnnouncement() error", err)
t.Error("GetUrgentAnnouncement() Expected error")
}
}
func TestGetAPIKeys(t *testing.T) {
_, err := b.GetAPIKeys()
if err == nil {
t.Error("test failed - GetAPIKeys() error", err)
t.Error("GetAPIKeys() Expected error")
}
}
func TestRemoveAPIKey(t *testing.T) {
_, err := b.RemoveAPIKey(APIKeyParams{APIKeyID: "1337"})
if err == nil {
t.Error("test failed - RemoveAPIKey() error", err)
t.Error("RemoveAPIKey() Expected error")
}
}
func TestDisableAPIKey(t *testing.T) {
_, err := b.DisableAPIKey(APIKeyParams{APIKeyID: "1337"})
if err == nil {
t.Error("test failed - DisableAPIKey() error", err)
t.Error("DisableAPIKey() Expected error")
}
}
func TestEnableAPIKey(t *testing.T) {
_, err := b.EnableAPIKey(APIKeyParams{APIKeyID: "1337"})
if err == nil {
t.Error("test failed - EnableAPIKey() error", err)
t.Error("EnableAPIKey() Expected error")
}
}
func TestGetTrollboxMessages(t *testing.T) {
_, err := b.GetTrollboxMessages(ChatGetParams{Count: 5})
if err != nil {
t.Error("test failed - GetTrollboxMessages() error", err)
t.Error("GetTrollboxMessages() error", err)
}
}
@@ -103,126 +103,126 @@ func TestSendTrollboxMessage(t *testing.T) {
ChannelID: 1337,
Message: "Hello,World!"})
if err == nil {
t.Error("test failed - SendTrollboxMessage() error", err)
t.Error("SendTrollboxMessage() Expected error")
}
}
func TestGetTrollboxChannels(t *testing.T) {
_, err := b.GetTrollboxChannels()
if err != nil {
t.Error("test failed - GetTrollboxChannels() error", err)
t.Error("GetTrollboxChannels() error", err)
}
}
func TestGetTrollboxConnectedUsers(t *testing.T) {
_, err := b.GetTrollboxConnectedUsers()
if err == nil {
t.Error("test failed - GetTrollboxConnectedUsers() error", err)
t.Error("GetTrollboxConnectedUsers() Expected error")
}
}
func TestGetAccountExecutions(t *testing.T) {
_, err := b.GetAccountExecutions(&GenericRequestParams{})
if err == nil {
t.Error("test failed - GetAccountExecutions() error", err)
t.Error("GetAccountExecutions() Expected error")
}
}
func TestGetAccountExecutionTradeHistory(t *testing.T) {
_, err := b.GetAccountExecutionTradeHistory(&GenericRequestParams{})
if err == nil {
t.Error("test failed - GetAccountExecutionTradeHistory() error", err)
t.Error("GetAccountExecutionTradeHistory() Expected error")
}
}
func TestGetFundingHistory(t *testing.T) {
_, err := b.GetFundingHistory()
if err == nil {
t.Error("test failed - GetFundingHistory() error", err)
t.Error("GetFundingHistory() Expected error")
}
}
func TestGetInstruments(t *testing.T) {
_, err := b.GetInstruments(&GenericRequestParams{})
if err != nil {
t.Error("test failed - GetInstruments() error", err)
t.Error("GetInstruments() error", err)
}
}
func TestGetActiveInstruments(t *testing.T) {
_, err := b.GetActiveInstruments(&GenericRequestParams{})
if err != nil {
t.Error("test failed - GetActiveInstruments() error", err)
t.Error("GetActiveInstruments() error", err)
}
}
func TestGetActiveAndIndexInstruments(t *testing.T) {
_, err := b.GetActiveAndIndexInstruments()
if err != nil {
t.Error("test failed - GetActiveAndIndexInstruments() error", err)
t.Error("GetActiveAndIndexInstruments() error", err)
}
}
func TestGetActiveIntervals(t *testing.T) {
_, err := b.GetActiveIntervals()
if err == nil {
t.Error("test failed - GetActiveIntervals() error", err)
t.Error("GetActiveIntervals() Expected error")
}
}
func TestGetCompositeIndex(t *testing.T) {
_, err := b.GetCompositeIndex(&GenericRequestParams{})
if err == nil {
t.Error("test failed - GetCompositeIndex() error", err)
t.Error("GetCompositeIndex() Expected error")
}
}
func TestGetIndices(t *testing.T) {
_, err := b.GetIndices()
if err != nil {
t.Error("test failed - GetIndices() error", err)
t.Error("GetIndices() error", err)
}
}
func TestGetInsuranceFundHistory(t *testing.T) {
_, err := b.GetInsuranceFundHistory(&GenericRequestParams{})
if err != nil {
t.Error("test failed - GetInsuranceFundHistory() error", err)
t.Error("GetInsuranceFundHistory() error", err)
}
}
func TestGetLeaderboard(t *testing.T) {
_, err := b.GetLeaderboard(LeaderboardGetParams{})
if err != nil {
t.Error("test failed - GetLeaderboard() error", err)
t.Error("GetLeaderboard() error", err)
}
}
func TestGetAliasOnLeaderboard(t *testing.T) {
_, err := b.GetAliasOnLeaderboard()
if err == nil {
t.Error("test failed - GetAliasOnLeaderboard() error", err)
t.Error("GetAliasOnLeaderboard() Expected error")
}
}
func TestGetLiquidationOrders(t *testing.T) {
_, err := b.GetLiquidationOrders(&GenericRequestParams{})
if err != nil {
t.Error("test failed - GetLiquidationOrders() error", err)
t.Error("GetLiquidationOrders() error", err)
}
}
func TestGetCurrentNotifications(t *testing.T) {
_, err := b.GetCurrentNotifications()
if err == nil {
t.Error("test failed - GetCurrentNotifications() error", err)
t.Error("GetCurrentNotifications() Expected error")
}
}
func TestAmendOrder(t *testing.T) {
_, err := b.AmendOrder(&OrderAmendParams{})
if err == nil {
t.Error("test failed - AmendOrder() error", err)
t.Error("AmendOrder() Expected error")
}
}
@@ -232,126 +232,126 @@ func TestCreateOrder(t *testing.T) {
ClOrdID: "mm_bitmex_1a/oemUeQ4CAJZgP3fjHsA",
OrderQty: 98})
if err == nil {
t.Error("test failed - CreateOrder() error", err)
t.Error("CreateOrder() Expected error")
}
}
func TestCancelOrders(t *testing.T) {
_, err := b.CancelOrders(&OrderCancelParams{})
if err == nil {
t.Error("test failed - CancelOrders() error", err)
t.Error("CancelOrders() Expected error")
}
}
func TestCancelAllOrders(t *testing.T) {
_, err := b.CancelAllExistingOrders(OrderCancelAllParams{})
if err == nil {
t.Error("test failed - CancelAllOrders(orderCancellation *exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error)", err)
t.Error("CancelAllOrders(orderCancellation *exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error)", err)
}
}
func TestAmendBulkOrders(t *testing.T) {
_, err := b.AmendBulkOrders(OrderAmendBulkParams{})
if err == nil {
t.Error("test failed - AmendBulkOrders() error", err)
t.Error("AmendBulkOrders() Expected error")
}
}
func TestCreateBulkOrders(t *testing.T) {
_, err := b.CreateBulkOrders(OrderNewBulkParams{})
if err == nil {
t.Error("test failed - CreateBulkOrders() error", err)
t.Error("CreateBulkOrders() Expected error")
}
}
func TestCancelAllOrdersAfterTime(t *testing.T) {
_, err := b.CancelAllOrdersAfterTime(OrderCancelAllAfterParams{})
if err == nil {
t.Error("test failed - CancelAllOrdersAfterTime() error", err)
t.Error("CancelAllOrdersAfterTime() Expected error")
}
}
func TestClosePosition(t *testing.T) {
_, err := b.ClosePosition(OrderClosePositionParams{})
if err == nil {
t.Error("test failed - ClosePosition() error", err)
t.Error("ClosePosition() Expected error")
}
}
func TestGetOrderbook(t *testing.T) {
_, err := b.GetOrderbook(OrderBookGetL2Params{Symbol: "XBT"})
if err != nil {
t.Error("test failed - GetOrderbook() error", err)
t.Error("GetOrderbook() error", err)
}
}
func TestGetPositions(t *testing.T) {
_, err := b.GetPositions(PositionGetParams{})
if err == nil {
t.Error("test failed - GetPositions() error", err)
t.Error("GetPositions() Expected error")
}
}
func TestIsolatePosition(t *testing.T) {
_, err := b.IsolatePosition(PositionIsolateMarginParams{Symbol: "XBT"})
if err == nil {
t.Error("test failed - IsolatePosition() error", err)
t.Error("IsolatePosition() Expected error")
}
}
func TestLeveragePosition(t *testing.T) {
_, err := b.LeveragePosition(PositionUpdateLeverageParams{})
if err == nil {
t.Error("test failed - LeveragePosition() error", err)
t.Error("LeveragePosition() Expected error")
}
}
func TestUpdateRiskLimit(t *testing.T) {
_, err := b.UpdateRiskLimit(PositionUpdateRiskLimitParams{})
if err == nil {
t.Error("test failed - UpdateRiskLimit() error", err)
t.Error("UpdateRiskLimit() Expected error")
}
}
func TestTransferMargin(t *testing.T) {
_, err := b.TransferMargin(PositionTransferIsolatedMarginParams{})
if err == nil {
t.Error("test failed - TransferMargin() error", err)
t.Error("TransferMargin() Expected error")
}
}
func TestGetQuotesByBuckets(t *testing.T) {
_, err := b.GetQuotesByBuckets(&QuoteGetBucketedParams{})
if err == nil {
t.Error("test failed - GetQuotesByBuckets() error", err)
t.Error("GetQuotesByBuckets() Expected error")
}
}
func TestGetSettlementHistory(t *testing.T) {
_, err := b.GetSettlementHistory(&GenericRequestParams{})
if err != nil {
t.Error("test failed - GetSettlementHistory() error", err)
t.Error("GetSettlementHistory() error", err)
}
}
func TestGetStats(t *testing.T) {
_, err := b.GetStats()
if err != nil {
t.Error("test failed - GetStats() error", err)
t.Error("GetStats() error", err)
}
}
func TestGetStatsHistorical(t *testing.T) {
_, err := b.GetStatsHistorical()
if err != nil {
t.Error("test failed - GetStatsHistorical() error", err)
t.Error("GetStatsHistorical() error", err)
}
}
func TestGetStatSummary(t *testing.T) {
_, err := b.GetStatSummary()
if err != nil {
t.Error("test failed - GetStatSummary() error", err)
t.Error("GetStatSummary() error", err)
}
}
@@ -361,14 +361,14 @@ func TestGetTrade(t *testing.T) {
StartTime: time.Now().Format(time.RFC3339),
Reverse: true})
if err != nil {
t.Error("test failed - GetTrade() error", err)
t.Error("GetTrade() error", err)
}
}
func TestGetPreviousTrades(t *testing.T) {
_, err := b.GetPreviousTrades(&TradeGetBucketedParams{})
if err == nil {
t.Error("test failed - GetPreviousTrades() error", err)
t.Error("GetPreviousTrades() Expected error")
}
}
@@ -404,7 +404,7 @@ func TestGetFee(t *testing.T) {
// CryptocurrencyTradeFee Basic
if resp, err := b.GetFee(feeBuilder); resp != float64(0.00075) || err != nil {
t.Error(err)
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.00075), resp)
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.00075), resp)
}
// CryptocurrencyTradeFee High quantity
@@ -412,7 +412,7 @@ func TestGetFee(t *testing.T) {
feeBuilder.Amount = 1000
feeBuilder.PurchasePrice = 1000
if resp, err := b.GetFee(feeBuilder); resp != float64(750) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(750), resp)
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(750), resp)
t.Error(err)
}
@@ -420,7 +420,7 @@ func TestGetFee(t *testing.T) {
feeBuilder = setFeeBuilder()
feeBuilder.IsMaker = true
if resp, err := b.GetFee(feeBuilder); resp != float64(0.0005) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.0005), resp)
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.0005), resp)
t.Error(err)
}
@@ -428,7 +428,7 @@ func TestGetFee(t *testing.T) {
feeBuilder = setFeeBuilder()
feeBuilder.PurchasePrice = -1000
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Error(err)
}
@@ -436,7 +436,7 @@ func TestGetFee(t *testing.T) {
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Error(err)
}
@@ -444,7 +444,7 @@ func TestGetFee(t *testing.T) {
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.CyptocurrencyDepositFee
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Error(err)
}
@@ -453,7 +453,7 @@ func TestGetFee(t *testing.T) {
feeBuilder.FeeType = exchange.InternationalBankDepositFee
feeBuilder.FiatCurrency = currency.HKD
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Error(err)
}
@@ -462,7 +462,7 @@ func TestGetFee(t *testing.T) {
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
feeBuilder.FiatCurrency = currency.HKD
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Error(err)
}
}
@@ -607,12 +607,12 @@ func TestGetAccountInfo(t *testing.T) {
if apiKey != "" || apiSecret != "" {
_, err := b.GetAccountInfo()
if err != nil {
t.Error("Test Failed - GetAccountInfo() error", err)
t.Error("GetAccountInfo() error", err)
}
} else {
_, err := b.GetAccountInfo()
if err == nil {
t.Error("Test Failed - GetAccountInfo() error")
t.Error("GetAccountInfo() error")
}
}
}
@@ -620,7 +620,7 @@ func TestGetAccountInfo(t *testing.T) {
func TestModifyOrder(t *testing.T) {
_, err := b.ModifyOrder(&exchange.ModifyOrder{OrderID: "1337"})
if err == nil {
t.Error("Test Failed - ModifyOrder() error")
t.Error("ModifyOrder() error")
}
}
@@ -685,12 +685,12 @@ func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := b.GetDepositAddress(currency.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
t.Error("GetDepositAddress() error", err)
}
} else {
_, err := b.GetDepositAddress(currency.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
t.Error("GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -13,6 +13,7 @@ import (
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/protocol"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
"github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler"
@@ -90,9 +91,36 @@ func (b *Bitmex) SetDefaults() {
Supports: exchange.FeaturesSupported{
REST: true,
Websocket: true,
RESTCapabilities: exchange.ProtocolFeatures{
AutoPairUpdates: true,
TickerBatching: true,
RESTCapabilities: protocol.Features{
TickerBatching: true,
TickerFetching: true,
TradeFetching: true,
OrderbookFetching: true,
AutoPairUpdates: true,
AccountInfo: true,
GetOrder: true,
GetOrders: true,
CancelOrders: true,
CancelOrder: true,
SubmitOrder: true,
SubmitOrders: true,
ModifyOrder: true,
DepositHistory: true,
WithdrawalHistory: true,
UserTradeHistory: true,
CryptoDeposit: true,
CryptoWithdrawal: true,
TradeFee: true,
CryptoWithdrawalFee: true,
},
WebsocketCapabilities: protocol.Features{
TradeFetching: true,
OrderbookFetching: true,
Subscribe: true,
Unsubscribe: true,
AuthenticatedEndpoints: true,
AccountInfo: true,
DeadMansSwitch: true,
},
WithdrawPermissions: exchange.AutoWithdrawCryptoWithAPIPermission |
exchange.WithdrawCryptoWithEmail |
@@ -113,13 +141,6 @@ func (b *Bitmex) SetDefaults() {
b.API.Endpoints.URL = b.API.Endpoints.URLDefault
b.API.Endpoints.WebsocketURL = bitmexWSURL
b.Websocket = wshandler.New()
b.Websocket.Functionality = wshandler.WebsocketTradeDataSupported |
wshandler.WebsocketOrderbookSupported |
wshandler.WebsocketSubscribeSupported |
wshandler.WebsocketUnsubscribeSupported |
wshandler.WebsocketAuthenticatedEndpointsSupported |
wshandler.WebsocketAccountDataSupported |
wshandler.WebsocketDeadMansSwitchSupported
b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout
b.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit
@@ -149,6 +170,7 @@ func (b *Bitmex) Setup(exch *config.ExchangeConfig) error {
Connector: b.WsConnect,
Subscriber: b.Subscribe,
UnSubscriber: b.Unsubscribe,
Features: &b.Features.Supports.WebsocketCapabilities,
})
if err != nil {
return err