Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -612,8 +612,7 @@ var unsupportedAssets = []asset.Item{
var unsupportedExchangeNames = []string{
"testexch",
"bitflyer", // Bitflyer has many "ErrNotYetImplemented, which is true, but not what we care to test for here
"btse", // TODO rm once timeout issues resolved
"poloniex", // outdated API // TODO rm once updated
"btse", // TODO rm once timeout issues resolved
}

// cryptoChainPerExchange holds the deposit address chain per exchange
Expand Down
2 changes: 2 additions & 0 deletions config/versions/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
v0 "github.com/thrasher-corp/gocryptotrader/config/versions/v0"
v1 "github.com/thrasher-corp/gocryptotrader/config/versions/v1"
v10 "github.com/thrasher-corp/gocryptotrader/config/versions/v10"
v11 "github.com/thrasher-corp/gocryptotrader/config/versions/v11"
v2 "github.com/thrasher-corp/gocryptotrader/config/versions/v2"
v3 "github.com/thrasher-corp/gocryptotrader/config/versions/v3"
v4 "github.com/thrasher-corp/gocryptotrader/config/versions/v4"
Expand All @@ -26,4 +27,5 @@ func init() {
Manager.registerVersion(8, &v8.Version{})
Manager.registerVersion(9, &v9.Version{})
Manager.registerVersion(10, &v10.Version{})
Manager.registerVersion(11, &v11.Version{})
}
34 changes: 34 additions & 0 deletions config/versions/v11/v11.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package v11

import (
"context"
"errors"

"github.com/buger/jsonparser"
)

// Version is an ExchangeVersion to replace deprecated WS and REST endpoints for Poloniex
type Version struct{}

// Exchanges returns just Poloniex
func (v *Version) Exchanges() []string { return []string{"Poloniex"} }

// UpgradeExchange replaces deprecated WS and REST endpoints
func (v *Version) UpgradeExchange(_ context.Context, e []byte) ([]byte, error) {
for _, key := range []string{"WebsocketSpotURL", "RestSpotURL"} {
url, err := jsonparser.GetString(e, "api", "urlEndpoints", key)
if err != nil && !errors.Is(err, jsonparser.KeyPathNotFoundError) {
return e, err
}
switch url {
case "wss://api2.poloniex.com", "https://poloniex.com":
e = jsonparser.Delete(e, "api", "urlEndpoints", key)
}
}
return e, nil
}

// DowngradeExchange is a no-op for v11
func (v *Version) DowngradeExchange(_ context.Context, e []byte) ([]byte, error) {
return e, nil
}
54 changes: 54 additions & 0 deletions config/versions/v11/v11_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package v11_test

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v11 "github.com/thrasher-corp/gocryptotrader/config/versions/v11"
)

func TestExchanges(t *testing.T) {
t.Parallel()
assert.Equal(t, []string{"Poloniex"}, new(v11.Version).Exchanges())
}

func TestUpgradeExchange(t *testing.T) {
t.Parallel()

for _, tt := range []struct {
in string
urlType string
exp string
}{
{"https://poloniex.com", "RestSpotURL", ""},
{"https://poloniex.private-proxy.com", "RestSpotURL", `"RestSpotURL": "https://poloniex.private-proxy.com"`},
{"wss://api2.poloniex.com", "WebsocketSpotURL", ""},
{"wss://poloniex.private-proxy.com", "WebsocketSpotURL", `"WebsocketSpotURL": "wss://poloniex.private-proxy.com"`},
} {
t.Run(tt.in, func(t *testing.T) {
t.Parallel()
in := []byte(`{"name":"Poloniex","api":{"urlEndpoints":{"` + tt.urlType + `": "` + tt.in + `"}}}`)
out, err := new(v11.Version).UpgradeExchange(t.Context(), in)
require.NoError(t, err)
exp := `{"name":"Poloniex","api":{"urlEndpoints":{` + tt.exp + `}}}`
assert.Equal(t, exp, string(out))
})
}

in := []byte(`{"name":"Poloniex","api":{}`)
out, err := new(v11.Version).UpgradeExchange(t.Context(), in)
require.NoError(t, err, "UpgradeExchange must not error when urlEndpoints is missing")
assert.Equal(t, string(in), string(out), "UpgradeExchange should return same input and no error when urlEndpoints is missing")

_, err = new(v11.Version).UpgradeExchange(t.Context(), []byte(`{"name":"Poloniex","api":{"urlEndpoints":{"WebsocketSpotURL": 42}}}`))
require.ErrorContains(t, err, "Value is not a string", "UpgradeExchange must error correctly on string value")
}

func TestDowngradeExchange(t *testing.T) {
t.Parallel()
in := []byte(`{"name":"Poloniex","api":{"urlEndpoints":{"WebsocketSpotURL": 42}}}`)
out, err := new(v11.Version).DowngradeExchange(t.Context(), in)
require.NoError(t, err)
require.Equal(t, string(in), string(out), "DowngradeExchange must not change json")
}
27 changes: 16 additions & 11 deletions config_example.json
Original file line number Diff line number Diff line change
Expand Up @@ -2308,31 +2308,36 @@
"delimiter": "_"
},
"useGlobalFormat": true,
"assetTypes": [
"spot"
],
"pairs": {
"spot": {
"assetEnabled": true,
"enabled": "BTC_LTC,BTC_ETH,BTC_DOGE,BTC_DASH,BTC_XRP",
"available": "BTC_SC,BTC_GNT,USDC_LTC,PAX_ETH,USDT_BSVBEAR,BUSD_BNB,USDT_WRX,USDT_IBVOL,USDT_ETH,BTC_ETC,USDC_ETH,BTC_POLY,BTC_ATOM,USDT_ATOM,TRX_STEEM,USDT_NEO,USDT_XRPBULL,USDT_AVA,USDT_DASH,USDT_ZRX,USDT_TRXBEAR,USDT_PAX,DAI_ETH,BTC_NEO,TRX_JST,BTC_FXC,USDT_ETC,USDT_ZEC,BTC_STORJ,USDT_GNT,USDT_QTUM,BTC_FOAM,TRX_BTT,USDT_BCHC,BTC_XFIL,USDC_XMR,TRX_WIN,USDT_SNX,BTC_LEND,USDT_BSVBULL,BTC_DOGE,BTC_REP,USDT_REP,BTC_STRAT,USDT_EOS,BTC_BAT,BTC_BCHABC,USDT_BUSD,BTC_XRP,BTC_ARDR,USDT_LINKBULL,BTC_CHR,USDT_CUSDT,TRX_WRX,USDT_XRP,ETH_ZEC,BTC_KNC,USDT_DOGE,BTC_LPT,USDT_BTT,ETH_COMP,USDC_GRIN,USDC_DASH,USDT_GRIN,USDT_XTZ,BTC_GAS,USDT_DAI,TRX_NEO,USDT_LINKBEAR,TRX_CHR,BTC_MDT,USDT_XMR,BTC_DCR,BTC_CVC,USDT_BNB,BTC_NXT,BTC_LSK,BTC_OMG,BTC_QTUM,BTC_BCHSV,BTC_SNX,BTC_MANA,USDC_EOS,DAI_BTC,BTC_SWFTC,TRX_BNB,BTC_STEEM,USDJ_BTC,USDJ_BTT,USDT_LRC,USDT_BAL,BNB_BTC,USDC_DOGE,BTC_TRX,BTC_XTZ,TRX_XTZ,USDT_MATIC,USDT_BCHBEAR,USDT_SWFTC,BTC_LTC,USDC_XRP,BTC_NMR,TRX_MATIC,USDT_XRPBEAR,BTC_ZEC,BTC_SNT,USDT_SC,USDT_BCHSV,TRX_ETH,BUSD_BTC,BTC_DASH,ETH_BAT,BTC_LOOM,TRX_SNX,ETH_ZRX,USDC_BCHABC,USDC_ETC,USDT_BULL,PAX_BTC,USDJ_TRX,BTC_WRX,BTC_BTS,USDT_LTC,BTC_LINK,USDT_USDJ,TRX_SWFTC,USDT_LINK,TRX_AVA,USDC_USDT,USDT_JST,TRX_FXC,USDT_CHR,USDT_XFIL,BTC_ETHBNT,BTC_LRC,USDT_BAT,USDC_ATOM,USDT_WIN,ETH_EOS,USDT_TRX,TRX_MDT,BTC_AVA,BTC_XEM,USDT_BTC,BTC_EOS,USDT_LSK,BTC_MATIC,USDT_FXC,USDT_STEEM,USDC_BCHSV,USDT_TRXBULL,USDT_EOSBULL,USDT_LEND,ETH_ETC,USDT_MANA,USDT_ETHBULL,USDT_REN,USDT_COMP,BTC_XMR,BTC_ETH,BTC_ZRX,USDC_BTC,TRX_XRP,USDT_ETHBEAR,USDT_BVOL,ETH_BAL,USDT_MDT,BTC_BNT,USDC_ZEC,USDT_BCHABC,TRX_LINK,BTC_MKR,USDT_BCN,USDT_EOSBEAR,BTC_REN,USDT_STR,USDC_STR,USDT_BEAR,USDT_BCHBULL,BTC_STR,USDC_TRX,USDT_MKR"
},
"futures": {
"assetEnabled": true,
"enabled": "XBT_USDT_PERP,ETH_USDT_PERP,BCH_USDT_PERP",
"available": "BNB_USDT_PERP,TRX_USDT_PERP,LTC_USDT_PERP,APT_USDT_PERP,1000PEPE_USDT_PERP,1000SHIB_USDT_PERP,BTC_USDT_PERP,DOGE_USDT_PERP,AVAX_USDT_PERP,XRP_USDT_PERP,SOL_USDT_PERP,ETH_USDT_PERP,BCH_USDT_PERP"
}
}
},
"api": {
"authenticatedSupport": false,
"authenticatedWebsocketApiSupport": false,
"endpoints": {
"url": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API",
"urlSecondary": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API",
"websocketURL": "NON_DEFAULT_HTTP_LINK_TO_WEBSOCKET_EXCHANGE_API"
},
"credentials": {
"key": "Key",
"secret": "Secret"
"key": "",
"secret": ""
},
"credentialsValidator": {
"requiresKey": true,
"requiresSecret": true
},
"urlEndpoints": {
"RestSpotURL": "https://api.poloniex.com",
"WebsocketPrivateURL": "wss://ws.poloniex.com/ws/private",
"WebsocketSpotURL": "wss://ws.poloniex.com/ws/public",
"WebsocketFuturesURL": "wss://ws.poloniex.com/ws/v3/public",
"WebsocketFuturesPrivateURL": "wss://ws.poloniex.com/ws/v3/private"
}
},
"features": {
Expand All @@ -2347,7 +2352,7 @@
},
"enabled": {
"autoPairUpdates": true,
"websocketAPI": false
"websocketAPI": true
}
},
"bankAccounts": [
Expand Down
8 changes: 8 additions & 0 deletions exchanges/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,10 @@ func (u URL) String() string {
return websocketPrivateURL
case WebsocketSpotSupplementary:
return websocketSpotSupplementaryURL
case WebsocketFutures:
return websocketFuturesURL
case WebsocketFuturesPrivate:
return websocketFuturesPrivateURL
case ChainAnalysis:
return chainAnalysisURL
case EdgeCase1:
Expand Down Expand Up @@ -1414,6 +1418,10 @@ func getURLTypeFromString(ep string) (URL, error) {
return WebsocketPrivate, nil
case websocketSpotSupplementaryURL:
return WebsocketSpotSupplementary, nil
case websocketFuturesURL:
return WebsocketFutures, nil
case websocketFuturesPrivateURL:
return WebsocketFuturesPrivate, nil
case chainAnalysisURL:
return ChainAnalysis, nil
case edgeCase1URL:
Expand Down
4 changes: 4 additions & 0 deletions exchanges/exchange_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1649,6 +1649,8 @@ func TestString(t *testing.T) {
{WebsocketTrade, websocketTradeURL},
{WebsocketPrivate, websocketPrivateURL},
{WebsocketSpotSupplementary, websocketSpotSupplementaryURL},
{WebsocketFutures, websocketFuturesURL},
{WebsocketFuturesPrivate, websocketFuturesPrivateURL},
{ChainAnalysis, chainAnalysisURL},
{EdgeCase1, edgeCase1URL},
{EdgeCase2, edgeCase2URL},
Expand Down Expand Up @@ -1813,6 +1815,8 @@ func TestGetGetURLTypeFromString(t *testing.T) {
{Endpoint: websocketTradeURL, Expected: WebsocketTrade},
{Endpoint: websocketPrivateURL, Expected: WebsocketPrivate},
{Endpoint: websocketSpotSupplementaryURL, Expected: WebsocketSpotSupplementary},
{Endpoint: websocketFuturesURL, Expected: WebsocketFutures},
{Endpoint: websocketFuturesPrivateURL, Expected: WebsocketFuturesPrivate},
{Endpoint: chainAnalysisURL, Expected: ChainAnalysis},
{Endpoint: edgeCase1URL, Expected: EdgeCase1},
{Endpoint: edgeCase2URL, Expected: EdgeCase2},
Expand Down
6 changes: 6 additions & 0 deletions exchanges/exchange_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ const (
WebsocketTrade
WebsocketPrivate
WebsocketSpotSupplementary
WebsocketFutures
WebsocketFuturesPrivate
ChainAnalysis
EdgeCase1
EdgeCase2
Expand All @@ -304,6 +306,8 @@ const (
websocketTradeURL = "WebsocketTradeURL"
websocketPrivateURL = "WebsocketPrivateURL"
websocketSpotSupplementaryURL = "WebsocketSpotSupplementaryURL"
websocketFuturesURL = "WebsocketFuturesURL"
websocketFuturesPrivateURL = "WebsocketFuturesPrivateURL"
chainAnalysisURL = "ChainAnalysisURL"
edgeCase1URL = "EdgeCase1URL"
edgeCase2URL = "EdgeCase2URL"
Expand All @@ -328,6 +332,8 @@ var keyURLs = []URL{
WebsocketTrade,
WebsocketPrivate,
WebsocketSpotSupplementary,
WebsocketFutures,
WebsocketFuturesPrivate,
ChainAnalysis,
EdgeCase1,
EdgeCase2,
Expand Down
1 change: 1 addition & 0 deletions exchanges/kline/kline_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ type Candle struct {
Low float64
Close float64
Volume float64
QuoteVolume float64
ValidationIssues string
}

Expand Down
9 changes: 4 additions & 5 deletions exchanges/mock/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,13 @@ func MatchAndGetResponse(mockData []HTTPResponse, requestVals url.Values, isQuer
}

mockVals := url.Values{}
var err error
if json.Valid([]byte(data)) {
something := make(map[string]any)
err = json.Unmarshal([]byte(data), &something)
if err != nil {
dataMap := make(map[string]any)
if err := json.Unmarshal([]byte(data), &dataMap); err != nil {
return nil, err
}

for k, v := range something {
for k, v := range dataMap {
switch val := v.(type) {
case string:
mockVals.Add(k, val)
Expand All @@ -277,6 +275,7 @@ func MatchAndGetResponse(mockData []HTTPResponse, requestVals url.Values, isQuer
}
}
} else {
var err error
mockVals, err = url.ParseQuery(data)
if err != nil {
return nil, err
Expand Down
49 changes: 33 additions & 16 deletions exchanges/order/order_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ var (
ErrCannotLiquidate = errors.New("cannot liquidate position")

ErrUnknownTrackingMode = errors.New("unknown tracking mode")
ErrGetFailed = errors.New("get order failed")
ErrPlaceFailed = errors.New("place order failed")
ErrCancelFailed = errors.New("cancel order failed")
)

// Submit contains all properties of an order that may be required
Expand Down Expand Up @@ -104,8 +107,16 @@ type Submit struct {
TrackingMode TrackingMode
TrackingValue float64

// LimitTrackingMode specifies the limit price offset used to place a limit order relative to the market price.
LimitTrackingMode TrackingMode
LimitTrackingValue float64

// RFQDisabled, when set, attempts to route the order to the exchange CLOB. Currently only supported by Coinbase
RFQDisabled bool

// SlippageTolerance used to control the maximum slippage ratio, the value range is greater than 0 and less than 1
// https://api-docs.poloniex.com/spot/api/private/order
SlippageTolerance float64
}

// SubmitResponse is what is returned after submitting an order to an exchange
Expand Down Expand Up @@ -157,13 +168,14 @@ const (
// are required to be populated
type Modify struct {
// Order Identifiers
Exchange string
OrderID string
ClientOrderID string
Type Type
Side Side
AssetType asset.Item
Pair currency.Pair
Exchange string
OrderID string
ClientOrderID string
NewClientOrderID string
Type Type
Side Side
AssetType asset.Item
Pair currency.Pair

// Change fields
TimeInForce TimeInForce
Expand All @@ -176,6 +188,10 @@ type Modify struct {
TriggerPriceType PriceType

RiskManagementModes RiskManagementModes

// SlippageTolerance used to control the maximum slippage ratio, the value range is greater than 0 and less than 1
// https://api-docs.poloniex.com/spot/api/private/order
SlippageTolerance float64
}

// ModifyResponse is an order modifying return type
Expand Down Expand Up @@ -372,6 +388,7 @@ const (
AnyType
Liquidation
Trigger
LimitMaker
OCO // One-cancels-the-other order
ConditionalStop // One-way stop order
TWAP // time-weighted average price
Expand All @@ -380,10 +397,11 @@ const (
MarketMakerProtection

// Hybrid order types
StopLimit = Stop | Limit
StopMarket = Stop | Market
TakeProfitMarket = TakeProfit | Market
Bracket = Stop | TakeProfit
StopLimit = Stop | Limit
StopMarket = Stop | Market
TakeProfitMarket = TakeProfit | Market
TrailingStopLimit = TrailingStop | Limit
Bracket = Stop | TakeProfit
)

// order-type string representations
Expand All @@ -399,9 +417,11 @@ const (
orderTakeProfit = "TAKE PROFIT"
orderTakeProfitMarket = "TAKE PROFIT MARKET"
orderTrailingStop = "TRAILING_STOP"
orderTrailingStopLimit = "TRAILING_STOP_LIMIT"
orderIOS = "IOS"
orderLiquidation = "LIQUIDATION"
orderTrigger = "TRIGGER"
orderLimitMaker = "LIMIT_MAKER"
orderOCO = "OCO"
orderOptimalLimit = "OPTIMAL_LIMIT"
orderMarketMakerProtection = "MMP"
Expand All @@ -413,22 +433,19 @@ const (
var AllOrderTypes = Limit |
Market |
Stop |
StopLimit |
StopMarket |
TakeProfit |
TakeProfitMarket |
TrailingStop |
IOS |
AnyType |
Liquidation |
Trigger |
LimitMaker |
OCO |
ConditionalStop |
TWAP |
Chase |
OptimalLimit |
MarketMakerProtection |
Bracket
MarketMakerProtection

// Side enforces a standard for order sides across the code base
type Side uint32
Expand Down
Loading
Loading